From 87dec3b3d3f01b3e71c4ba5b92de4d60997ee2e3 Mon Sep 17 00:00:00 2001 From: SridharNagaraj Date: Thu, 20 Feb 2025 12:26:55 +0530 Subject: [PATCH 01/46] Support OpenAIFunction Custom object Schema --- .../openai/chatcompletion/OpenAIFunction.java | 37 +++++++- .../openai/chatcompletion/JsonSchemaTest.java | 87 +++++++++++++++++++ .../samples/demos/lights/App.java | 8 +- .../samples/demos/lights/LightModel.java | 7 ++ .../demos/lights/LightModelTypeConverter.java | 23 +++++ .../samples/demos/lights/LightsPlugin.java | 11 +++ 6 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModelTypeConverter.java diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java index ad6dbadbb..dbf6ff95c 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java @@ -7,19 +7,25 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.microsoft.semantickernel.exceptions.SKException; +import com.microsoft.semantickernel.orchestration.responseformat.ResponseSchemaGenerator; import com.microsoft.semantickernel.semanticfunctions.InputVariable; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionMetadata; +import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; class OpenAIFunction { + private static final ConcurrentHashMap SCHEMA_CACHE = new ConcurrentHashMap<>(); private final String pluginName; private final String name; @@ -159,14 +165,17 @@ private static String getSchemaForFunctionParameter(@Nullable InputVariable para entries.add("\"type\":\"" + type + "\""); // Add description if present + String description =null; if (parameter != null && parameter.getDescription() != null && !parameter.getDescription() .isEmpty()) { - String description = parameter.getDescription(); + description = parameter.getDescription(); description = description.replaceAll("\\r?\\n|\\r", ""); description = description.replace("\"", "\\\""); - - description = String.format("\"description\":\"%s\"", description); - entries.add(description); + entries.add(String.format("\"description\":\"%s\"", description)); + } + // If custom type, generate schema + if("object".equalsIgnoreCase(type)) { + return getObjectSchema(parameter.getType(), description); } // Add enum options if parameter is an enum @@ -219,4 +228,24 @@ private static String getJavaTypeToOpenAiFunctionType(String javaType) { return "object"; } } + + private static String getObjectSchema(String type, String description){ + String schema= ""; + try { + if(SCHEMA_CACHE.containsKey(type)) { + schema= SCHEMA_CACHE.get(type); + } else { + Class clazz = Class.forName(type); + schema = ResponseSchemaGenerator.jacksonGenerator().generateSchema(clazz); + SCHEMA_CACHE.put(type, schema); + } + } catch (ClassNotFoundException | SKException ignored) { + + } + Map properties = BinaryData.fromString(schema).toObject(Map.class); + if(StringUtils.isNotBlank(description)) { + properties.put("description", description); + } + return BinaryData.fromObject(properties).toString(); + } } diff --git a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java index d0cdc0d9c..3b42981a5 100644 --- a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java +++ b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java @@ -1,10 +1,17 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.aiservices.openai.chatcompletion; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; import com.fasterxml.jackson.core.JsonProcessingException; import com.microsoft.semantickernel.orchestration.responseformat.JsonSchemaResponseFormat; +import com.microsoft.semantickernel.plugin.KernelPlugin; +import com.microsoft.semantickernel.plugin.KernelPluginFactory; +import com.microsoft.semantickernel.semanticfunctions.KernelFunction; +import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; +import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; public class JsonSchemaTest { @@ -24,4 +31,84 @@ public void jacksonGenerationTest() throws JsonProcessingException { "\"type\":\"object\",\"properties\":{\"bar\":{}}")); } + @Test + public void openAIFunctionTest() { + KernelPlugin plugin = KernelPluginFactory.createFromObject( + new TestPlugin(), + "test"); + + Assertions.assertNotNull(plugin); + Assertions.assertEquals(plugin.getName(), "test"); + Assertions.assertEquals(plugin.getFunctions().size(), 3); + + KernelFunction testFunction = plugin.getFunctions() + .get("asyncPersonFunction"); + OpenAIFunction openAIFunction = OpenAIFunction.build( + testFunction.getMetadata(), + plugin.getName()); + System.out.println(openAIFunction.getFunctionDefinition()); + + } + + + public static class TestPlugin { + + @DefineKernelFunction + public String testFunction( + @KernelFunctionParameter(name = "input", description = "input string") String input) { + return "test" + input; + } + + @DefineKernelFunction(returnType = "int") + public Mono asyncTestFunction( + @KernelFunctionParameter(name = "input") String input) { + return Mono.just(1); + } + + @DefineKernelFunction(returnType = "int", description = "test function description", + name = "asyncPersonFunction", returnDescription = "test return description") + public Mono asyncPersonFunction( + @KernelFunctionParameter(name = "person",description = "input person", type = Person.class) Person person, + @KernelFunctionParameter(name = "input", description = "input string") String input) { + return Mono.just(1); + } + } + + private static enum Title { + MS, + MRS, + MR + } + + public static class Person { + @JsonPropertyDescription("The name of the person.") + private String name; + @JsonPropertyDescription("The age of the person.") + private int age; + @JsonPropertyDescription("The title of the person.") + private Title title; + + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public Title getTitle() { + return title; + } + + public void setTitle(Title title) { + this.title = title; + } + } + } diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/App.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/App.java index 08a8f3b52..21a4b1c8c 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/App.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/App.java @@ -70,9 +70,7 @@ public static void main(String[] args) throws Exception { ChatCompletionService.class); ContextVariableTypes - .addGlobalConverter(ContextVariableTypeConverter.builder(LightModel.class) - .toPromptString(new Gson()::toJson) - .build()); + .addGlobalConverter(new LightModelTypeConverter()); KernelHooks hook = new KernelHooks(); @@ -99,9 +97,7 @@ public static void main(String[] args) throws Exception { InvocationContext invocationContext = new Builder() .withReturnMode(InvocationReturnMode.LAST_MESSAGE_ONLY) .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) - .withContextVariableConverter(ContextVariableTypeConverter.builder(LightModel.class) - .toPromptString(new Gson()::toJson) - .build()) + .withContextVariableConverter(new LightModelTypeConverter()) .build(); // Create a history to store the conversation diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModel.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModel.java index 072763a91..e7958507b 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModel.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModel.java @@ -1,10 +1,17 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.samples.demos.lights; +import com.fasterxml.jackson.annotation.JsonPropertyDescription; + public class LightModel { + @JsonPropertyDescription("The unique identifier of the light") private int id; + + @JsonPropertyDescription("The name of the light") private String name; + + @JsonPropertyDescription("The state of the light") private Boolean isOn; public LightModel(int id, String name, Boolean isOn) { diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModelTypeConverter.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModelTypeConverter.java new file mode 100644 index 000000000..250de12e4 --- /dev/null +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModelTypeConverter.java @@ -0,0 +1,23 @@ +package com.microsoft.semantickernel.samples.demos.lights; + +import com.google.gson.Gson; +import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter; + +public class LightModelTypeConverter extends ContextVariableTypeConverter { + private static final Gson gson = new Gson(); + + public LightModelTypeConverter() { + super( + LightModel.class, + obj -> { + if(obj instanceof String) { + return gson.fromJson((String)obj, LightModel.class); + } else { + return gson.fromJson(gson.toJson(obj), LightModel.class); + } + }, + (types, lightModel) -> gson.toJson(lightModel), + json -> gson.fromJson(json, LightModel.class) + ); + } +} diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightsPlugin.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightsPlugin.java index d2f4ed08e..fa11addb5 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightsPlugin.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightsPlugin.java @@ -24,6 +24,17 @@ public List getLights() { return lights; } + @DefineKernelFunction(name = "add_light", description = "Adds a new light") + public String addLight( + @KernelFunctionParameter(name = "newLight", description = "new Light Details", type = LightModel.class) LightModel light) { + if( light != null) { + System.out.println("Adding light " + light.getName()); + lights.add(light); + return "Light added"; + } + return "Light failed to added"; + } + @DefineKernelFunction(name = "change_state", description = "Changes the state of the light") public LightModel changeState( @KernelFunctionParameter(name = "id", description = "The ID of the light to change", type = int.class) int id, From b71458aa8c500778da5c945460a0a552f770c6d1 Mon Sep 17 00:00:00 2001 From: SridharNagaraj Date: Sun, 23 Feb 2025 13:52:51 +0530 Subject: [PATCH 02/46] Remove cache and updated testcase --- .../aiservices/openai/chatcompletion/OpenAIFunction.java | 9 ++------- .../aiservices/openai/chatcompletion/JsonSchemaTest.java | 4 +++- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java index dbf6ff95c..e1f2f2497 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java @@ -25,7 +25,6 @@ import javax.annotation.Nullable; class OpenAIFunction { - private static final ConcurrentHashMap SCHEMA_CACHE = new ConcurrentHashMap<>(); private final String pluginName; private final String name; @@ -230,15 +229,11 @@ private static String getJavaTypeToOpenAiFunctionType(String javaType) { } private static String getObjectSchema(String type, String description){ - String schema= ""; + String schema= "{ \"type\" : \"object\" }"; try { - if(SCHEMA_CACHE.containsKey(type)) { - schema= SCHEMA_CACHE.get(type); - } else { Class clazz = Class.forName(type); schema = ResponseSchemaGenerator.jacksonGenerator().generateSchema(clazz); - SCHEMA_CACHE.put(type, schema); - } + } catch (ClassNotFoundException | SKException ignored) { } diff --git a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java index 3b42981a5..68c8dae88 100644 --- a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java +++ b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java @@ -46,7 +46,9 @@ public void openAIFunctionTest() { OpenAIFunction openAIFunction = OpenAIFunction.build( testFunction.getMetadata(), plugin.getName()); - System.out.println(openAIFunction.getFunctionDefinition()); + + String parameters = "{\"type\":\"object\",\"required\":[\"person\",\"input\"],\"properties\":{\"input\":{\"type\":\"string\",\"description\":\"input string\"},\"person\":{\"type\":\"object\",\"properties\":{\"age\":{\"type\":\"integer\",\"description\":\"The age of the person.\"},\"name\":{\"type\":\"string\",\"description\":\"The name of the person.\"},\"title\":{\"type\":\"string\",\"enum\":[\"MS\",\"MRS\",\"MR\"],\"description\":\"The title of the person.\"}},\"required\":[\"age\",\"name\",\"title\"],\"additionalProperties\":false,\"description\":\"input person\"}}}"; + Assertions.assertEquals(parameters, openAIFunction.getFunctionDefinition().getParameters().toString()); } From f5986bdd5595bbb1de298081ad4cd9f4281803a2 Mon Sep 17 00:00:00 2001 From: GitHub Date: Tue, 25 Feb 2025 17:19:21 -0800 Subject: [PATCH 03/46] [maven-release-plugin] prepare for next development iteration --- aiservices/google/pom.xml | 2 +- aiservices/huggingface/pom.xml | 2 +- aiservices/openai/pom.xml | 2 +- api-test/integration-tests/pom.xml | 2 +- api-test/pom.xml | 2 +- data/semantickernel-data-azureaisearch/pom.xml | 2 +- data/semantickernel-data-jdbc/pom.xml | 2 +- data/semantickernel-data-redis/pom.xml | 2 +- pom.xml | 4 ++-- samples/pom.xml | 2 +- samples/semantickernel-concepts/pom.xml | 2 +- .../semantickernel-syntax-examples/pom.xml | 2 +- samples/semantickernel-demos/booking-agent-m365/pom.xml | 2 +- samples/semantickernel-demos/pom.xml | 2 +- .../semantickernel-spring-starter/pom.xml | 2 +- samples/semantickernel-demos/sk-presidio-sample/pom.xml | 2 +- samples/semantickernel-learn-resources/pom.xml | 2 +- samples/semantickernel-sample-plugins/pom.xml | 2 +- .../semantickernel-openapi-plugin/pom.xml | 2 +- .../semantickernel-presidio-plugin/pom.xml | 2 +- .../semantickernel-text-splitter-plugin/pom.xml | 2 +- semantickernel-api/pom.xml | 2 +- semantickernel-bom/pom.xml | 4 ++-- semantickernel-experimental/pom.xml | 2 +- 24 files changed, 26 insertions(+), 26 deletions(-) diff --git a/aiservices/google/pom.xml b/aiservices/google/pom.xml index 8c6ac73d7..97c6957c7 100644 --- a/aiservices/google/pom.xml +++ b/aiservices/google/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT ../../pom.xml diff --git a/aiservices/huggingface/pom.xml b/aiservices/huggingface/pom.xml index 8ca1d183f..68803583a 100644 --- a/aiservices/huggingface/pom.xml +++ b/aiservices/huggingface/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT ../../pom.xml diff --git a/aiservices/openai/pom.xml b/aiservices/openai/pom.xml index 34c1477d2..56ad51830 100644 --- a/aiservices/openai/pom.xml +++ b/aiservices/openai/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT ../../pom.xml diff --git a/api-test/integration-tests/pom.xml b/api-test/integration-tests/pom.xml index 64c122e98..49624531b 100644 --- a/api-test/integration-tests/pom.xml +++ b/api-test/integration-tests/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel api-test - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/api-test/pom.xml b/api-test/pom.xml index 674f733b0..e5dde576c 100644 --- a/api-test/pom.xml +++ b/api-test/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/data/semantickernel-data-azureaisearch/pom.xml b/data/semantickernel-data-azureaisearch/pom.xml index c53436bb0..24cf4174c 100644 --- a/data/semantickernel-data-azureaisearch/pom.xml +++ b/data/semantickernel-data-azureaisearch/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT ../../pom.xml diff --git a/data/semantickernel-data-jdbc/pom.xml b/data/semantickernel-data-jdbc/pom.xml index 0379f9815..624779e98 100644 --- a/data/semantickernel-data-jdbc/pom.xml +++ b/data/semantickernel-data-jdbc/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT ../../pom.xml diff --git a/data/semantickernel-data-redis/pom.xml b/data/semantickernel-data-redis/pom.xml index e2c18c2d0..69e7c293d 100644 --- a/data/semantickernel-data-redis/pom.xml +++ b/data/semantickernel-data-redis/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT ../../pom.xml diff --git a/pom.xml b/pom.xml index ab526a96e..30963f54b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT pom https://www.github.com/microsoft/semantic-kernel @@ -837,6 +837,6 @@ https://github.com/microsoft/semantic-kernel scm:git:https://github.com/microsoft/semantic-kernel.git scm:git:https://github.com/microsoft/semantic-kernel.git - java-1.4.3 + HEAD diff --git a/samples/pom.xml b/samples/pom.xml index d78bc0dd3..d42af3c9e 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-concepts/pom.xml b/samples/semantickernel-concepts/pom.xml index 70f831df2..d94740e8a 100644 --- a/samples/semantickernel-concepts/pom.xml +++ b/samples/semantickernel-concepts/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml b/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml index a37752084..1f6bc1811 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-concepts - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-demos/booking-agent-m365/pom.xml b/samples/semantickernel-demos/booking-agent-m365/pom.xml index 69c9d527e..d7a6ec3b5 100644 --- a/samples/semantickernel-demos/booking-agent-m365/pom.xml +++ b/samples/semantickernel-demos/booking-agent-m365/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-demos - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-demos/pom.xml b/samples/semantickernel-demos/pom.xml index 7a6e76f4a..eb3c0afe9 100644 --- a/samples/semantickernel-demos/pom.xml +++ b/samples/semantickernel-demos/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml b/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml index ad5b020b1..fd9822ebe 100644 --- a/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml +++ b/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-demos - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-demos/sk-presidio-sample/pom.xml b/samples/semantickernel-demos/sk-presidio-sample/pom.xml index 9277e1f8c..799d563b9 100644 --- a/samples/semantickernel-demos/sk-presidio-sample/pom.xml +++ b/samples/semantickernel-demos/sk-presidio-sample/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-demos - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-learn-resources/pom.xml b/samples/semantickernel-learn-resources/pom.xml index 904178d8b..293da2d3d 100644 --- a/samples/semantickernel-learn-resources/pom.xml +++ b/samples/semantickernel-learn-resources/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-sample-plugins/pom.xml b/samples/semantickernel-sample-plugins/pom.xml index d82def681..bb8db1393 100644 --- a/samples/semantickernel-sample-plugins/pom.xml +++ b/samples/semantickernel-sample-plugins/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml index 3bb0353cc..fa9f378d0 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml +++ b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-sample-plugins - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml b/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml index e06845d5c..8c012a6e1 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml +++ b/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-sample-plugins - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml b/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml index 9f9a298ab..a10f1cfcc 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml +++ b/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-sample-plugins - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/semantickernel-api/pom.xml b/semantickernel-api/pom.xml index efe7d2261..3176c82e6 100644 --- a/semantickernel-api/pom.xml +++ b/semantickernel-api/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT ../pom.xml diff --git a/semantickernel-bom/pom.xml b/semantickernel-bom/pom.xml index e9f338627..bb4d766fd 100644 --- a/semantickernel-bom/pom.xml +++ b/semantickernel-bom/pom.xml @@ -5,7 +5,7 @@ com.microsoft.semantic-kernel semantickernel-bom - 1.4.3 + 1.4.4-SNAPSHOT pom Semantic Kernel Java BOM @@ -290,6 +290,6 @@ https://github.com/microsoft/semantic-kernel scm:git:https://github.com/microsoft/semantic-kernel.git scm:git:https://github.com/microsoft/semantic-kernel.git - java-1.4.3 + HEAD diff --git a/semantickernel-experimental/pom.xml b/semantickernel-experimental/pom.xml index ce5f80556..1b3aa7847 100644 --- a/semantickernel-experimental/pom.xml +++ b/semantickernel-experimental/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.3 + 1.4.4-SNAPSHOT semantickernel-experimental From 7501d23e1bd2de141d68887385310c03541504ba Mon Sep 17 00:00:00 2001 From: Phil Jirsa Date: Thu, 27 Feb 2025 08:43:00 -0600 Subject: [PATCH 04/46] update opentelemetry span attributes --- .../implementation/telemetry/ChatCompletionSpan.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/telemetry/ChatCompletionSpan.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/telemetry/ChatCompletionSpan.java index 87945860a..9fa465ed9 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/telemetry/ChatCompletionSpan.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/telemetry/ChatCompletionSpan.java @@ -104,8 +104,8 @@ public void endSpanWithUsage(ChatCompletions chatCompletions) { CompletionsUsage usage = chatCompletions.getUsage(); getSpan().setStatus(StatusCode.OK); getSpan() - .setAttribute("gen_ai.response.completion_tokens", usage.getCompletionTokens()); - getSpan().setAttribute("gen_ai.response.prompt_tokens", usage.getPromptTokens()); + .setAttribute("gen_ai.usage.output_tokens", usage.getCompletionTokens()); + getSpan().setAttribute("gen_ai.usage.input_tokens", usage.getPromptTokens()); close(); } From 016aa2220f61610a713c98fe88dd4f0c24132273 Mon Sep 17 00:00:00 2001 From: Phil Jirsa Date: Sun, 2 Mar 2025 07:48:33 -0600 Subject: [PATCH 05/46] update otel test --- .../semantickernel/aiservices/openai/OtelCaptureTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/OtelCaptureTest.java b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/OtelCaptureTest.java index c9136c554..5c3444b3a 100644 --- a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/OtelCaptureTest.java +++ b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/OtelCaptureTest.java @@ -118,9 +118,9 @@ public void otelChatCaptureTest() { spans.get(0).getAttributes().get(AttributeKey.stringKey("gen_ai.system"))); Assertions.assertEquals(21, spans.get(0).getAttributes() - .get(AttributeKey.longKey("gen_ai.response.completion_tokens"))); + .get(AttributeKey.longKey("gen_ai.usage.output_tokens"))); Assertions.assertEquals(42, spans.get(0).getAttributes() - .get(AttributeKey.longKey("gen_ai.response.prompt_tokens"))); + .get(AttributeKey.longKey("gen_ai.usage.input_tokens"))); } } From f01c624981f060ea8238183101415777a4c4cb94 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 14 Apr 2025 22:19:12 -0700 Subject: [PATCH 06/46] Add KernelArguments and deprecated KernelFunctionArguments --- .../chatcompletion/GeminiChatCompletion.java | 4 +- .../chatcompletion/OpenAIChatCompletion.java | 8 +- .../OpenAIFunctionToolCall.java | 8 +- .../OpenAiChatCompletionTest.java | 4 +- .../tests/Example03_ArgumentsTest.java | 4 +- ...xample05_InlineFunctionDefinitionTest.java | 8 +- .../semantickernel/tests/KernelHooksTest.java | 4 +- .../semantickernel/tests/RenderingTest.java | 16 +- .../plugins/ConversationSummaryPlugin.java | 4 +- .../Example11_WebSearchQueries.java | 4 +- .../syntaxexamples/Example20_HuggingFace.java | 4 +- .../Example43_GetModelResult.java | 4 +- .../syntaxexamples/Example57_KernelHooks.java | 16 +- .../Example62_CustomAIServiceSelector.java | 6 +- .../Example30_ChatWithPrompts.java | 4 +- .../functions/Example03_Arguments.java | 4 +- .../Example05_InlineFunctionDefinition.java | 8 +- .../functions/Example09_FunctionTypes.java | 17 +- ...Example27_PromptFunctionsUsingChatGPT.java | 4 +- .../Example60_AdvancedMethodFunctions.java | 6 +- .../Example98_GeminiFunctionCalling.java | 4 +- .../java/CustomTypes_Example.java | 8 +- .../java/FunctionTelemetry_Example.java | 4 +- .../java/FunctionsHandlebars_Example.java | 4 +- .../java/FunctionsWithinPrompts_Example.java | 6 +- .../java/KernelFunctionYaml_Example.java | 6 +- .../Example07_BingAndGooglePlugins.java | 8 +- .../Example13_ConversationSummaryPlugin.java | 10 +- ...eMethodFunctionsWithMultipleArguments.java | 4 +- .../Example64_MultiplePromptTemplates.java | 4 +- .../com/microsoft/semantickernel/Main.java | 4 +- .../CreatingFunctions.java | 4 +- .../FunctionsWithinPrompts.java | 6 +- .../SerializingPrompts.java | 6 +- .../documentationexamples/Templates.java | 6 +- .../documentationexamples/UsingTheKernel.java | 6 +- .../plugins/ConversationSummaryPlugin.java | 4 +- .../openapi/OpenAPIHttpRequestPlugin.java | 14 +- .../SemanticKernelOpenAPIImporter.java | 4 +- .../com/microsoft/semantickernel/Kernel.java | 10 +- .../hooks/FunctionInvokedEvent.java | 10 +- .../hooks/FunctionInvokingEvent.java | 10 +- .../hooks/PreToolCallEvent.java | 8 +- .../hooks/PromptRenderedEvent.java | 10 +- .../hooks/PromptRenderingEvent.java | 10 +- .../telemetry/FunctionSpan.java | 4 +- .../tokenizer/DefaultPromptTemplate.java | 4 +- .../tokenizer/blocks/CodeBlock.java | 12 +- .../tokenizer/blocks/CodeRendering.java | 4 +- .../tokenizer/blocks/FunctionIdBlock.java | 4 +- .../tokenizer/blocks/NamedArgBlock.java | 6 +- .../tokenizer/blocks/TextBlock.java | 4 +- .../tokenizer/blocks/TextRendering.java | 4 +- .../tokenizer/blocks/ValBlock.java | 4 +- .../tokenizer/blocks/VarBlock.java | 4 +- .../orchestration/FunctionInvocation.java | 12 +- .../semanticfunctions/KernelArguments.java | 410 ++++++++++++++++++ .../semanticfunctions/KernelFunction.java | 4 +- .../KernelFunctionArguments.java | 142 +----- .../KernelFunctionFromMethod.java | 22 +- .../KernelFunctionFromPrompt.java | 8 +- .../semanticfunctions/PromptTemplate.java | 2 +- .../services/AIServiceSelector.java | 7 +- .../services/BaseAIServiceSelector.java | 10 +- .../services/OrderedAIServiceSelector.java | 88 ++-- .../handlebars/HandlebarsPromptTemplate.java | 24 +- .../KernelFunctionFromMethodTest.java | 32 +- .../PromptTemplateFactoryTest.java | 2 +- .../services/AIServiceSelectorTest.java | 4 +- .../HandlebarsPromptTemplateTest.java | 14 +- .../semantickernel/CodeTokenizerTest.java | 11 +- 71 files changed, 739 insertions(+), 410 deletions(-) create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java diff --git a/aiservices/google/src/main/java/com/microsoft/semantickernel/aiservices/google/chatcompletion/GeminiChatCompletion.java b/aiservices/google/src/main/java/com/microsoft/semantickernel/aiservices/google/chatcompletion/GeminiChatCompletion.java index e226b4c66..2bd45c022 100644 --- a/aiservices/google/src/main/java/com/microsoft/semantickernel/aiservices/google/chatcompletion/GeminiChatCompletion.java +++ b/aiservices/google/src/main/java/com/microsoft/semantickernel/aiservices/google/chatcompletion/GeminiChatCompletion.java @@ -32,7 +32,7 @@ import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.semanticfunctions.InputVariable; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.chatcompletion.AuthorRole; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; @@ -436,7 +436,7 @@ public Mono performFunctionCall(@Nullable Kernel kernel, ? new ContextVariableTypes() : invocationContext.getContextVariableTypes(); - KernelFunctionArguments.Builder arguments = KernelFunctionArguments.builder(); + KernelArguments.Builder arguments = KernelArguments.builder(); geminiFunction.getFunctionCall().getArgs().getFieldsMap().forEach((key, value) -> { arguments.withVariable(key, value.getStringValue()); }); diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java index b842e43d0..33f46fc27 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java @@ -61,7 +61,7 @@ import com.microsoft.semantickernel.orchestration.responseformat.JsonResponseSchema; import com.microsoft.semantickernel.orchestration.responseformat.JsonSchemaResponseFormat; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.chatcompletion.AuthorRole; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; @@ -629,7 +629,7 @@ private Mono> invokeFunctionTool( contextVariableTypes)); function = hookResult.getFunction(); - KernelFunctionArguments arguments = hookResult.getArguments(); + KernelArguments arguments = hookResult.getArguments(); return function .invokeAsync(kernel) @@ -673,7 +673,7 @@ private OpenAIFunctionToolCall extractOpenAIFunctionToolCall( String pluginName = parts.length > 1 ? parts[0] : ""; String fnName = parts.length > 1 ? parts[1] : parts[0]; - KernelFunctionArguments arguments = KernelFunctionArguments.builder().build(); + KernelArguments arguments = KernelArguments.builder().build(); ObjectMapper mapper = new ObjectMapper(); JsonNode jsonToolCallArguments = mapper.readTree(toolCall.getFunction().getArguments()); @@ -1144,7 +1144,7 @@ private static ChatRequestAssistantMessage formAssistantMessage( asstMessage.setToolCalls( toolCalls.stream() .map(toolCall -> { - KernelFunctionArguments arguments = toolCall.getArguments(); + KernelArguments arguments = toolCall.getArguments(); String args = arguments != null && !arguments.isEmpty() ? arguments.entrySet().stream() diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunctionToolCall.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunctionToolCall.java index 18111330d..b7999cf00 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunctionToolCall.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunctionToolCall.java @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.aiservices.openai.chatcompletion; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import javax.annotation.Nullable; /** @@ -23,7 +23,7 @@ public class OpenAIFunctionToolCall { /// Gets a name/value collection of the arguments to the function, if any. @Nullable - private final KernelFunctionArguments arguments; + private final KernelArguments arguments; /** * Creates a new instance of the {@link OpenAIFunctionToolCall} class. @@ -37,7 +37,7 @@ public OpenAIFunctionToolCall( @Nullable String id, @Nullable String pluginName, String functionName, - @Nullable KernelFunctionArguments arguments) { + @Nullable KernelArguments arguments) { this.id = id; this.pluginName = pluginName; this.functionName = functionName; @@ -83,7 +83,7 @@ public String getFunctionName() { * @return A name/value collection of the arguments to the function, if any. */ @Nullable - public KernelFunctionArguments getArguments() { + public KernelArguments getArguments() { if (arguments == null) { return null; } diff --git a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAiChatCompletionTest.java b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAiChatCompletionTest.java index 05aebc3d6..5a1be82a4 100644 --- a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAiChatCompletionTest.java +++ b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAiChatCompletionTest.java @@ -13,7 +13,7 @@ import com.azure.json.implementation.DefaultJsonReader; import com.microsoft.semantickernel.implementation.EmbeddedResourceLoader; import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.chatcompletion.AuthorRole; import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; import java.nio.charset.Charset; @@ -46,7 +46,7 @@ public void serializesToolCallsCorrectly() { "a-tool-id", "pluginName", "funcName", - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("id", "ca2fc6bc-1307-4da6-a009-d7bf88dec37b") .build())))); chatHistory.addMessage(new OpenAIChatMessageContent( diff --git a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/Example03_ArgumentsTest.java b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/Example03_ArgumentsTest.java index ac1821246..dd283952d 100644 --- a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/Example03_ArgumentsTest.java +++ b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/Example03_ArgumentsTest.java @@ -6,7 +6,7 @@ import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.syntaxexamples.functions.Example03_Arguments.StaticTextPlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -24,7 +24,7 @@ public void main() { KernelPlugin functionCollection = KernelPluginFactory .createFromObject(new StaticTextPlugin(), "text"); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withInput("Today is: ") .withVariable("day", "Monday") .build(); diff --git a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/Example05_InlineFunctionDefinitionTest.java b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/Example05_InlineFunctionDefinitionTest.java index f74268b25..d791ec9c2 100644 --- a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/Example05_InlineFunctionDefinitionTest.java +++ b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/Example05_InlineFunctionDefinitionTest.java @@ -10,9 +10,9 @@ import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; -import com.microsoft.semantickernel.services.textcompletion.TextGenerationService; + import java.time.Instant; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; @@ -68,7 +68,7 @@ public void main(WireMockRuntimeInfo wmRuntimeInfo) { var result = kernel.invokeAsync(excuseFunction) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withInput("I missed the F1 final race") .build()) .block(); @@ -79,7 +79,7 @@ public void main(WireMockRuntimeInfo wmRuntimeInfo) { result = kernel.invokeAsync(excuseFunction) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withInput("sorry I forgot your birthday") .build()) .block(); diff --git a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/KernelHooksTest.java b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/KernelHooksTest.java index 16b9cadaf..4a128fb16 100644 --- a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/KernelHooksTest.java +++ b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/KernelHooksTest.java @@ -12,7 +12,7 @@ import com.microsoft.semantickernel.hooks.KernelHook.FunctionInvokingHook; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.OutputVariable; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; @@ -90,7 +90,7 @@ public void getUsageAsync(WireMockRuntimeInfo wmRuntimeInfo) { kernel.invokeAsync( excuseFunction) .withArguments( - KernelFunctionArguments + KernelArguments .builder() .withVariable("input", "I missed the F1 final race") .build()) diff --git a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/RenderingTest.java b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/RenderingTest.java index 3f09b50b2..ff4655d26 100644 --- a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/RenderingTest.java +++ b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/RenderingTest.java @@ -12,7 +12,7 @@ import com.microsoft.semantickernel.aiservices.openai.textcompletion.OpenAITextGenerationService; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; @@ -49,7 +49,7 @@ public void textSemanticKernelTemplateXml() { """) .withTemplateFormat(PromptTemplateConfig.SEMANTIC_KERNEL_TEMPLATE_FORMAT) .build()) - .withArguments(KernelFunctionArguments + .withArguments(KernelArguments .builder() .withVariable("value", "\"hello world\"") .build()) @@ -71,7 +71,7 @@ public void textSemanticKernelTemplate() { """) .withTemplateFormat(PromptTemplateConfig.SEMANTIC_KERNEL_TEMPLATE_FORMAT) .build()) - .withArguments(KernelFunctionArguments + .withArguments(KernelArguments .builder() .withVariable("value", "{{$ignore}}") .withVariable("ignore", "dont show") @@ -94,7 +94,7 @@ public void textHandleBarsTemplate() { """) .withTemplateFormat("handlebars") .build()) - .withArguments(KernelFunctionArguments + .withArguments(KernelArguments .builder() .withVariable("value", "{{ignore}}") .withVariable("ignore", "dont show") @@ -117,7 +117,7 @@ public void chatSemanticKernelTemplateXml() { """) .withTemplateFormat(PromptTemplateConfig.SEMANTIC_KERNEL_TEMPLATE_FORMAT) .build()) - .withArguments(KernelFunctionArguments + .withArguments(KernelArguments .builder() .withVariable("value", "\"hello world\"") .build()) @@ -139,7 +139,7 @@ public void chatSemanticKernelTemplate() { """) .withTemplateFormat(PromptTemplateConfig.SEMANTIC_KERNEL_TEMPLATE_FORMAT) .build()) - .withArguments(KernelFunctionArguments + .withArguments(KernelArguments .builder() .withVariable("value", "{{$ignore}}") .withVariable("ignore", "dont show") @@ -162,7 +162,7 @@ public void chatHandleBarsTemplate() { """) .withTemplateFormat("handlebars") .build()) - .withArguments(KernelFunctionArguments + .withArguments(KernelArguments .builder() .withVariable("value", "{{ignore}}") .withVariable("ignore", "dont show") @@ -185,7 +185,7 @@ public void chatSemanticKernelTemplate2() { """) .withTemplateFormat(PromptTemplateConfig.SEMANTIC_KERNEL_TEMPLATE_FORMAT) .build()) - .withArguments(KernelFunctionArguments + .withArguments(KernelArguments .builder() .withVariable("value", "{{$ignore}}") .withVariable("ignore", "dont show") diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java index 089a4941e..f61d1d873 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java @@ -5,7 +5,7 @@ import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; import com.microsoft.semantickernel.text.TextChunker; @@ -71,7 +71,7 @@ private static Mono processAsync(KernelFunction func, String inp // The first parameter is the input text. return func.invokeAsync(kernel) .withArguments( - new KernelFunctionArguments.Builder() + KernelArguments.builder() .withInput(paragraph) .build()) .withResultType( diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example11_WebSearchQueries.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example11_WebSearchQueries.java index 63abdbccb..1386cc619 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example11_WebSearchQueries.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example11_WebSearchQueries.java @@ -4,7 +4,7 @@ import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.web.SearchUrlPlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; public class Example11_WebSearchQueries { @@ -19,7 +19,7 @@ public static void main(String[] args) { // Run var ask = "What's the largest building in Europe?"; - var kernelArguments = KernelFunctionArguments.builder() + var kernelArguments = KernelArguments.builder() .withVariable("query", ask) .build(); diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example20_HuggingFace.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example20_HuggingFace.java index a388c130e..14fccf0a0 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example20_HuggingFace.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example20_HuggingFace.java @@ -5,7 +5,7 @@ import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.aiservices.huggingface.HuggingFaceClient; import com.microsoft.semantickernel.aiservices.huggingface.services.HuggingFaceTextGenerationService; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.services.textcompletion.TextGenerationService; @@ -43,7 +43,7 @@ public static void runInferenceApiExampleAsync() { var result = kernel.invokeAsync(questionAnswerFunction) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("input", "What is New York?") .build()) .withResultType(String.class) diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example43_GetModelResult.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example43_GetModelResult.java index 9dc86a68f..7b1e5752e 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example43_GetModelResult.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example43_GetModelResult.java @@ -10,7 +10,7 @@ import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; @@ -61,7 +61,7 @@ public static void main(String[] args) { FunctionResult result = kernel.invokeAsync( myFunction) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("input", "travel") .build()) .block(); diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java index 0203f66c8..ffa09a677 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example57_KernelHooks.java @@ -24,7 +24,7 @@ import com.microsoft.semantickernel.hooks.PromptRenderedEvent; import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.OutputVariable; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; @@ -133,7 +133,7 @@ private static void getUsageAsync(Kernel kernel) { String input = "I missed the F1 final race"; var result = kernel.invokeAsync(excuseFunction) .withArguments( - KernelFunctionArguments + KernelArguments .builder() .withVariable("input", input) .build()) @@ -189,7 +189,7 @@ private static void getRenderedPromptAsync(Kernel kernel) { String input = "I missed the F1 final race"; var result = kernel.invokeAsync(excuseFunction) .withArguments( - KernelFunctionArguments + KernelArguments .builder() .withVariable("input", input) .build()) @@ -235,7 +235,7 @@ private static void changingResultAsync(Kernel kernel) { // Invoke prompt to trigger execution hooks. var result = kernel.invokeAsync(writerFunction) .withArguments( - KernelFunctionArguments.builder().build()) + KernelArguments.builder().build()) .block(); System.out.println("Function Result: " + result.getResult()); } @@ -275,7 +275,7 @@ private static void beforeInvokeCancellationAsync(Kernel kernel) { // Invoke prompt to trigger execution hooks. var result = kernel.invokeAsync(writerFunction) .withArguments( - KernelFunctionArguments.builder().build()) + KernelArguments.builder().build()) .block(); System.out.println("Function Result: " + result.getResult()); } catch (Exception e) { @@ -312,7 +312,7 @@ private static void afterInvokeCancellationAsync(Kernel kernel) { // Invoke prompt to trigger execution hooks. try { var result = kernel.invokeAsync(secondFunction) - .withArguments(KernelFunctionArguments.builder().build()) + .withArguments(KernelArguments.builder().build()) .block(); System.out.println("Function Result: " + result.getResult()); } catch (Exception e) { @@ -359,7 +359,7 @@ private static void chatCompletionHook(Kernel kernel) { // Invoke prompt to trigger execution hooks. var result = kernel.invokeAsync(writerFunction) .withArguments( - KernelFunctionArguments.builder().build()) + KernelArguments.builder().build()) .block(); System.out.println("Function Result: " + result.getResult()); } catch (Exception e) { @@ -403,7 +403,7 @@ private static void invocationHook(Kernel kernel) { try { // Invoke prompt to trigger execution hooks. var result = kernel.invokeAsync(writerFunction) - .withArguments(KernelFunctionArguments.builder().build()) + .withArguments(KernelArguments.builder().build()) .addKernelHooks(kernelHooks) .block(); System.out.println("Function Result: " + result.getResult()); diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example62_CustomAIServiceSelector.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example62_CustomAIServiceSelector.java index afa5b2e33..5e01d13a2 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example62_CustomAIServiceSelector.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example62_CustomAIServiceSelector.java @@ -9,7 +9,7 @@ import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.services.AIService; import com.microsoft.semantickernel.services.AIServiceCollection; @@ -67,7 +67,7 @@ public static void main(String[] args) { var prompt = "Hello AI, what can you do for me?"; - KernelFunctionArguments arguments = KernelFunctionArguments.builder().build(); + KernelArguments arguments = KernelArguments.builder().build(); KernelFunction func = KernelFunctionFromPrompt .builder() @@ -98,7 +98,7 @@ public AIServiceSelection trySelectAIService( @Nullable KernelFunction function, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, Map, AIService> services) { // Just get the first one diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/chatcompletion/Example30_ChatWithPrompts.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/chatcompletion/Example30_ChatWithPrompts.java index 1357cc476..04a7a34fe 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/chatcompletion/Example30_ChatWithPrompts.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/chatcompletion/Example30_ChatWithPrompts.java @@ -11,7 +11,7 @@ import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.TimePlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; import com.microsoft.semantickernel.services.ServiceNotFoundException; @@ -82,7 +82,7 @@ public static void main(String[] args) throws FileNotFoundException, ServiceNotF // Adding required arguments referenced by the prompt templates. - var arguments = KernelFunctionArguments + var arguments = KernelArguments .builder() .withVariable("selectedText", selectedText) .withVariable("startTime", DateTimeFormatter.ofPattern("hh:mm:ss a zz").format( diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example03_Arguments.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example03_Arguments.java index 2096386dd..7db37899c 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example03_Arguments.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example03_Arguments.java @@ -5,7 +5,7 @@ import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; import java.util.Locale; @@ -24,7 +24,7 @@ public static void main(String[] args) { KernelPlugin functionCollection = KernelPluginFactory .createFromObject(new StaticTextPlugin(), "text"); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withInput("Today is: ") .withVariable("day", "Monday") .build(); diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example05_InlineFunctionDefinition.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example05_InlineFunctionDefinition.java index 7ecf9a0da..52edb0dba 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example05_InlineFunctionDefinition.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example05_InlineFunctionDefinition.java @@ -11,10 +11,10 @@ import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; -import com.microsoft.semantickernel.services.textcompletion.TextGenerationService; + import java.time.Instant; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; @@ -82,7 +82,7 @@ public static void main(String[] args) throws ConfigurationException { var result = kernel .invokeAsync(excuseFunction) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withInput("I missed the F1 final race") .build()) .block(); @@ -90,7 +90,7 @@ public static void main(String[] args) throws ConfigurationException { result = kernel.invokeAsync(excuseFunction) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withInput("sorry I forgot your birthday") .build()) .block(); diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example09_FunctionTypes.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example09_FunctionTypes.java index c6c1fdffa..4c14ef54f 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example09_FunctionTypes.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example09_FunctionTypes.java @@ -9,7 +9,6 @@ import com.azure.core.credential.KeyCredential; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; -import com.microsoft.semantickernel.aiservices.openai.textcompletion.OpenAITextGenerationService; import com.microsoft.semantickernel.contextvariables.ContextVariable; import com.microsoft.semantickernel.contextvariables.ContextVariableType; import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter; @@ -17,11 +16,11 @@ import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; -import com.microsoft.semantickernel.services.textcompletion.TextGenerationService; + import java.nio.file.Path; import java.time.Instant; import java.time.OffsetDateTime; @@ -119,7 +118,7 @@ public static void main(String[] args) throws InterruptedException { result = kernel .invokeAsync(plugin.get("InputDateTimeWithStringResult")) .withArguments( - KernelFunctionArguments + KernelArguments .builder() .withVariable("currentDate", ContextVariable.of( @@ -135,7 +134,7 @@ public static void main(String[] args) throws InterruptedException { result = kernel.invokeAsync(plugin.get("MultipleInputsWithVoidResult")) .withArguments( - KernelFunctionArguments + KernelArguments .builder() .withVariable("x", "x string") .withVariable("y", 100) @@ -146,7 +145,7 @@ public static void main(String[] args) throws InterruptedException { result = kernel .invokeAsync(plugin.get("ComplexInputWithStringResult")) .withArguments( - KernelFunctionArguments + KernelArguments .builder() .withVariable( "complexObject", @@ -165,7 +164,7 @@ public String toString() { result = kernel .invokeAsync(plugin.get("InputStringTaskWithStringResult")) .withArguments( - KernelFunctionArguments + KernelArguments .builder() .withVariable("echoInput", "return this") .build()) @@ -175,7 +174,7 @@ public String toString() { result = kernel .invokeAsync(plugin.get("InputStringTaskWithVoidResult")) .withArguments( - KernelFunctionArguments + KernelArguments .builder() .withVariable("x", "x input") .build()) @@ -258,7 +257,7 @@ public String toString() { result = kernel.invokeAsync(plugin.get("MultipleComplexInputsWithVoidResult")) .withArguments( - KernelFunctionArguments + KernelArguments .builder() .withVariable("x", OffsetDateTime.of(1, 1, 1, 1, 1, 1, 1, ZoneOffset.UTC)) .withVariable("y", OffsetDateTime.of(1, 1, 1, 1, 1, 1, 1, ZoneOffset.UTC)) diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example27_PromptFunctionsUsingChatGPT.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example27_PromptFunctionsUsingChatGPT.java index f72ec2370..1f139e2ff 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example27_PromptFunctionsUsingChatGPT.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example27_PromptFunctionsUsingChatGPT.java @@ -9,7 +9,7 @@ import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; public class Example27_PromptFunctionsUsingChatGPT { @@ -54,7 +54,7 @@ public static void main(String[] args) { var result = func.invokeAsync(kernel) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("input", "Jupiter") .build()) .withResultType(ContextVariableTypes.getGlobalVariableTypeForClass(String.class)) diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example60_AdvancedMethodFunctions.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example60_AdvancedMethodFunctions.java index 87669a40c..dfbaeb722 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example60_AdvancedMethodFunctions.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example60_AdvancedMethodFunctions.java @@ -5,7 +5,7 @@ import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter; import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.plugin.KernelPluginFactory; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; import reactor.core.publisher.Mono; @@ -37,7 +37,7 @@ public static void main(String[] args) { var result = kernel .invokeAsync(FunctionsChainingPlugin.PluginName, "Function1") .withArguments( - KernelFunctionArguments + KernelArguments .builder() .build()) .withResultType(ContextVariableTypes.getGlobalVariableTypeForClass(MyCustomType.class)) @@ -82,7 +82,7 @@ public Mono function1Async(Kernel kernel) { // Execute another function return kernel .invokeAsync(PluginName, "Function2") - .withArguments(KernelFunctionArguments.builder().build()) + .withArguments(KernelArguments.builder().build()) .withResultType(ContextVariableTypes.getGlobalVariableTypeForClass( Example60_AdvancedMethodFunctions.MyCustomType.class)) .flatMap(value -> { diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example98_GeminiFunctionCalling.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example98_GeminiFunctionCalling.java index 0dd425f6e..b585775db 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example98_GeminiFunctionCalling.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example98_GeminiFunctionCalling.java @@ -13,7 +13,7 @@ import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.orchestration.ToolCallBehavior; import com.microsoft.semantickernel.plugin.KernelPluginFactory; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; @@ -140,7 +140,7 @@ public static void main(String[] args) throws NoSuchMethodException { var fn = kernel.getFunction(geminiFunction.getPluginName(), geminiFunction.getFunctionName()); - var arguments = KernelFunctionArguments.builder(); + var arguments = KernelArguments.builder(); geminiFunction.getFunctionCall().getArgs().getFieldsMap() .forEach((key, value) -> { arguments.withVariable(key, value.getStringValue()); diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/CustomTypes_Example.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/CustomTypes_Example.java index e809474dc..fcf2cc812 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/CustomTypes_Example.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/CustomTypes_Example.java @@ -13,7 +13,7 @@ import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.contextvariables.converters.ContextVariableJacksonConverter; import com.microsoft.semantickernel.exceptions.ConfigurationException; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import java.io.IOException; import java.util.Arrays; @@ -114,7 +114,7 @@ private static void exampleBuildingCustomConverter( Pet updated = kernel.invokePromptAsync( "Change Sandy's name to Daisy:\n{{$Sandy}}", - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("Sandy", sandy, typeConverter) .build()) .withTypeConverter(typeConverter) @@ -139,7 +139,7 @@ public static void exampleUsingJackson(ChatCompletionService chatCompletionServi // Invoke the prompt with the custom converter Pet updated = kernel.invokePromptAsync( "Increase Sandy's age by a year:\n{{$Sandy}}", - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("Sandy", sandy, typeConverter) .build()) .withTypeConverter(typeConverter) @@ -167,7 +167,7 @@ public static void exampleUsingGlobalTypes(ChatCompletionService chatCompletionS // No need to explicitly tell the invocation how to convert the type Pet updated = kernel.invokePromptAsync( "Sandy's is actually a cat correct this:\n{{$Sandy}}", - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("Sandy", sandy) .build()) .withResultType(Pet.class) diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionTelemetry_Example.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionTelemetry_Example.java index 1d228250c..4ca35a80f 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionTelemetry_Example.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionTelemetry_Example.java @@ -14,7 +14,7 @@ import com.microsoft.semantickernel.orchestration.ToolCallBehavior; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.syntaxexamples.functions.Example59_OpenAIFunctionCalling.PetPlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; import com.microsoft.semantickernel.services.ServiceNotFoundException; @@ -204,7 +204,7 @@ public static void testNestedCalls() { Analyse the following text: Hello There """, - KernelFunctionArguments.builder().build(), + KernelArguments.builder().build(), InvocationContext.builder() .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) .withReturnMode(InvocationReturnMode.NEW_MESSAGES_ONLY) diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionsHandlebars_Example.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionsHandlebars_Example.java index b13f06998..29ad37696 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionsHandlebars_Example.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionsHandlebars_Example.java @@ -4,7 +4,7 @@ import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.exceptions.ConfigurationException; import com.microsoft.semantickernel.plugin.KernelPluginFactory; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelPromptTemplateFactory; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; @@ -41,7 +41,7 @@ public static void main(String[] args) throws ConfigurationException, IOExceptio var renderedPrompt = promptTemplate.renderAsync( kernel, - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("choices", choices) .build(), null) diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionsWithinPrompts_Example.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionsWithinPrompts_Example.java index ceb9983ed..7e92e3e6e 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionsWithinPrompts_Example.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/FunctionsWithinPrompts_Example.java @@ -12,7 +12,7 @@ import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.ConversationSummaryPlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; @@ -154,7 +154,7 @@ public static void main(String[] args) throws ConfigurationException, IOExceptio // Invoke handlebars prompt var intent = kernel.invokeAsync(getIntent) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("request", request) .withVariable("choices", choices) .withVariable("history", historyString) @@ -173,7 +173,7 @@ public static void main(String[] args) throws ConfigurationException, IOExceptio // Get chat response var chatResult = kernel.invokeAsync(chat) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("request", request) .withVariable("history", historyString) .build()) diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/KernelFunctionYaml_Example.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/KernelFunctionYaml_Example.java index ec38aae05..10e9a014e 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/KernelFunctionYaml_Example.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/java/KernelFunctionYaml_Example.java @@ -13,7 +13,7 @@ import com.microsoft.semantickernel.implementation.telemetry.SemanticKernelTelemetry; import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionYaml; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import java.io.IOException; @@ -70,7 +70,7 @@ private static void handlebarsTemplate(Kernel kernel, FunctionResult result = function .invokeAsync(kernel) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("length", 5) .withVariable("topic", "dogs") .build()) @@ -91,7 +91,7 @@ private static void semanticKernelTemplate(Kernel kernel, FunctionResult result = function .invokeAsync(kernel) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("length", 5) .withVariable("topic", "cats") .build()) diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/plugin/Example07_BingAndGooglePlugins.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/plugin/Example07_BingAndGooglePlugins.java index 6ca71745b..2e4462fd2 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/plugin/Example07_BingAndGooglePlugins.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/plugin/Example07_BingAndGooglePlugins.java @@ -13,7 +13,7 @@ import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.web.WebSearchEnginePlugin; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.KernelPromptTemplateFactory; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; @@ -84,7 +84,7 @@ private static void example1Async(Kernel kernel, String searchPluginName) { // Run var question = "What's the largest building in the world?"; - var kernelArguments = KernelFunctionArguments.builder() + var kernelArguments = KernelArguments.builder() .withVariable("query", question) .build(); @@ -166,7 +166,7 @@ private static void example2Async(Kernel kernel) { .withDefaultExecutionSettings(promptExecutionSettings) .build(); - var kernelArguments = KernelFunctionArguments.builder() + var kernelArguments = KernelArguments.builder() .withVariable("question", question) .withVariable("externalInformation", "") .build(); @@ -187,7 +187,7 @@ private static void example2Async(Kernel kernel) { System.out.println("Information found:"); System.out.println(information); - kernelArguments = KernelFunctionArguments.builder() + kernelArguments = KernelArguments.builder() .withVariable("question", question) .withVariable("externalInformation", information) .build(); diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/plugin/Example13_ConversationSummaryPlugin.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/plugin/Example13_ConversationSummaryPlugin.java index b185c8946..63412b600 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/plugin/Example13_ConversationSummaryPlugin.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/plugin/Example13_ConversationSummaryPlugin.java @@ -12,7 +12,9 @@ import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.ConversationSummaryPlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments.Builder; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments.Builder; +import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import reactor.core.publisher.Mono; @@ -163,7 +165,7 @@ private static void getConversationActionItemsAsync() { conversationSummaryPlugin .get("GetConversationActionItems")) .withArguments( - new Builder() + KernelArguments.builder() .withInput(chatTranscript) .build()); System.out.println("Generated Action Items:"); @@ -179,7 +181,7 @@ private static void getConversationTopicsAsync() { Mono> summary = kernel .invokeAsync(conversationSummaryPlugin.get("GetConversationTopics")) .withArguments( - new Builder() + KernelArguments.builder() .withInput(chatTranscript) .build()); @@ -201,7 +203,7 @@ private static void conversationSummaryPluginAsync() { .getFunctions() .get("SummarizeConversation")) .withArguments( - new Builder() + KernelArguments.builder() .withInput(chatTranscript) .build()) .block(); diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/template/Example56_TemplateMethodFunctionsWithMultipleArguments.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/template/Example56_TemplateMethodFunctionsWithMultipleArguments.java index dc663d2d1..e26babe61 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/template/Example56_TemplateMethodFunctionsWithMultipleArguments.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/template/Example56_TemplateMethodFunctionsWithMultipleArguments.java @@ -10,7 +10,7 @@ import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.text.TextPlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.KernelPromptTemplateFactory; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; @@ -53,7 +53,7 @@ public static void main(String[] args) { System.out.println("======== TemplateMethodFunctionsWithMultipleArguments ========"); - var arguments = KernelFunctionArguments.builder() + var arguments = KernelArguments.builder() .withVariable("word2", " Potter") .build(); diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/template/Example64_MultiplePromptTemplates.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/template/Example64_MultiplePromptTemplates.java index ae534e70f..75568a6e9 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/template/Example64_MultiplePromptTemplates.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/template/Example64_MultiplePromptTemplates.java @@ -9,7 +9,7 @@ import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; import com.microsoft.semantickernel.semanticfunctions.AggregatorPromptTemplateFactory; import com.microsoft.semantickernel.semanticfunctions.HandlebarsPromptTemplateFactory; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.KernelPromptTemplateFactory; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; @@ -75,7 +75,7 @@ public static void runPrompt(Kernel kernel, String templateFormat, String prompt .withPromptTemplateFactory(templateFactory) .build(); - var arguments = KernelFunctionArguments.builder() + var arguments = KernelArguments.builder() .withVariable("name", "Bob") .build(); diff --git a/samples/semantickernel-demos/sk-presidio-sample/src/main/java/com/microsoft/semantickernel/Main.java b/samples/semantickernel-demos/sk-presidio-sample/src/main/java/com/microsoft/semantickernel/Main.java index 366d50148..ad14c3caf 100644 --- a/samples/semantickernel-demos/sk-presidio-sample/src/main/java/com/microsoft/semantickernel/Main.java +++ b/samples/semantickernel-demos/sk-presidio-sample/src/main/java/com/microsoft/semantickernel/Main.java @@ -13,7 +13,7 @@ import com.microsoft.semantickernel.presidio.AnonymizedText; import com.microsoft.semantickernel.presidio.AnonymizedTextConverter; import com.microsoft.semantickernel.presidio.RedactorPlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.ServiceNotFoundException; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; @@ -50,7 +50,7 @@ public static void main(String[] args) throws InterruptedException { .invokeAsync("redactor", "redact") .withResultType(AnonymizedText.class) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("input", text) .build()) .block() diff --git a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/CreatingFunctions.java b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/CreatingFunctions.java index 2cbb5baa0..ec3b9b951 100644 --- a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/CreatingFunctions.java +++ b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/CreatingFunctions.java @@ -12,7 +12,7 @@ import com.microsoft.semantickernel.orchestration.ToolCallBehavior; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.MathPlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; import java.util.Scanner; @@ -54,7 +54,7 @@ public static void main(String[] args) { // Test the math plugin var answer = kernel .invokeAsync(kernel.getFunction("MathPlugin", "sqrt")) - .withArguments(KernelFunctionArguments + .withArguments(KernelArguments .builder() .withVariable("number1", 12.0) .build()) diff --git a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/FunctionsWithinPrompts.java b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/FunctionsWithinPrompts.java index f271b7574..de394835d 100644 --- a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/FunctionsWithinPrompts.java +++ b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/FunctionsWithinPrompts.java @@ -16,7 +16,7 @@ import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.ConversationSummaryPlugin; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.chatcompletion.AuthorRole; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; @@ -139,7 +139,7 @@ public static void main(String[] args) { System.console().printf("User > "); String request = System.console().readLine(); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withVariable("request", request) .withVariable("choices", choices) .withVariable("history", history) @@ -162,7 +162,7 @@ public static void main(String[] args) { // Get chat response FunctionResult chatResult = chat.invokeAsync(kernel) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("request", request) .withVariable("history", history) .build()) diff --git a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/SerializingPrompts.java b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/SerializingPrompts.java index 3b5ba5915..233177e7d 100644 --- a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/SerializingPrompts.java +++ b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/SerializingPrompts.java @@ -11,7 +11,7 @@ import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.ConversationSummaryPlugin; import com.microsoft.semantickernel.semanticfunctions.HandlebarsPromptTemplateFactory; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionYaml; import com.microsoft.semantickernel.services.chatcompletion.AuthorRole; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; @@ -119,7 +119,7 @@ public static void main(String[] args) throws IOException { // var intent = kernel.invokeAsync(getIntent) - .withArguments(KernelFunctionArguments.builder() + .withArguments(KernelArguments.builder() .withVariable("request", userInput) .withVariable("choices", choices) .withVariable("history", historyString) @@ -134,7 +134,7 @@ public static void main(String[] args) throws IOException { } var reply = kernel.invokeAsync(prompts.get("Chat")) - .withArguments(KernelFunctionArguments.builder() + .withArguments(KernelArguments.builder() .withVariable("request", userInput) .withVariable("history", String.join("\n", diff --git a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/Templates.java b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/Templates.java index 41b096511..b830cd29f 100644 --- a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/Templates.java +++ b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/Templates.java @@ -14,7 +14,7 @@ import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.ConversationSummaryPlugin; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.services.chatcompletion.AuthorRole; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; @@ -154,7 +154,7 @@ public static void main(String[] args) { System.out.print("User > "); String request = scanner.nextLine(); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withVariable("request", request) .withVariable("choices", choices) .withVariable("chatHistory", history) @@ -180,7 +180,7 @@ public static void main(String[] args) { // Get chat response FunctionResult chatResult = chat.invokeAsync(kernel) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("request", request) .withVariable("history", history, chatHistoryType) .build()) diff --git a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/UsingTheKernel.java b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/UsingTheKernel.java index 73f137dc8..ebb0e4979 100644 --- a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/UsingTheKernel.java +++ b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/documentationexamples/UsingTheKernel.java @@ -10,7 +10,7 @@ import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.MathPlugin; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; public class UsingTheKernel { @@ -76,7 +76,7 @@ public static void main(String[] args) { var result = poemPlugin.get("ShortPoem") .invokeAsync(kernel) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withInput("The cat sat on a mat") .build()) .withResultType(String.class) @@ -88,7 +88,7 @@ public static void main(String[] args) { var root = mathPlugin.get("sqrt") .invokeAsync(kernel) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withInput(12) .build()) .withResultType(Double.class) diff --git a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java index 247fc48c1..1bd163711 100644 --- a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java +++ b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java @@ -5,7 +5,7 @@ import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; import com.microsoft.semantickernel.text.TextChunker; @@ -71,7 +71,7 @@ private static Mono processAsync(KernelFunction func, String inp // The first parameter is the input text. return func.invokeAsync(kernel) .withArguments( - new KernelFunctionArguments.Builder() + new KernelArguments.Builder() .withInput(paragraph) .build()) .withResultType( diff --git a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/OpenAPIHttpRequestPlugin.java b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/OpenAPIHttpRequestPlugin.java index e37b08916..58b3e5250 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/OpenAPIHttpRequestPlugin.java +++ b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/OpenAPIHttpRequestPlugin.java @@ -12,7 +12,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.microsoft.semantickernel.contextvariables.ContextVariable; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.PathItem; import io.swagger.v3.oas.models.parameters.Parameter; @@ -66,7 +66,7 @@ public OpenAPIHttpRequestPlugin( * @param arguments The arguments to the http request. * @return The body of the response. */ - public Mono execute(KernelFunctionArguments arguments) { + public Mono execute(KernelArguments arguments) { String body = getBody(arguments); String query = buildQueryString(arguments); String path = buildQueryPath(arguments); @@ -113,7 +113,7 @@ public Mono execute(KernelFunctionArguments arguments) { .doOnNext(response -> LOGGER.debug("Request response: {}", response)); } - private static @Nullable String getBody(KernelFunctionArguments arguments) { + private static @Nullable String getBody(KernelArguments arguments) { String body = null; if (arguments.containsKey("requestbody")) { ContextVariable requestBody = arguments.get("requestbody"); @@ -130,7 +130,7 @@ public Mono execute(KernelFunctionArguments arguments) { return body; } - private String buildQueryPath(KernelFunctionArguments arguments) { + private String buildQueryPath(KernelArguments arguments) { return getParameterStreamOfArguments(arguments) .filter(p -> p instanceof PathParameter) .reduce(path, (path, parameter) -> { @@ -142,7 +142,7 @@ private String buildQueryPath(KernelFunctionArguments arguments) { } private static String getRenderedParameter( - KernelFunctionArguments arguments, String name) { + KernelArguments arguments, String name) { ContextVariable value = arguments.get(name); if (value == null) { @@ -156,7 +156,7 @@ private static String getRenderedParameter( return URLEncoder.encode(rendered, StandardCharsets.US_ASCII); } - private String buildQueryString(KernelFunctionArguments arguments) { + private String buildQueryString(KernelArguments arguments) { return getParameterStreamOfArguments(arguments) .filter(p -> p instanceof QueryParameter) .map(parameter -> { @@ -168,7 +168,7 @@ private String buildQueryString(KernelFunctionArguments arguments) { } private Stream getParameterStreamOfArguments( - KernelFunctionArguments arguments) { + KernelArguments arguments) { if (operation.getParameters() == null) { return Stream.empty(); } diff --git a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/SemanticKernelOpenAPIImporter.java b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/SemanticKernelOpenAPIImporter.java index c1be538dc..2c01f0767 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/SemanticKernelOpenAPIImporter.java +++ b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/SemanticKernelOpenAPIImporter.java @@ -15,7 +15,7 @@ import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.semanticfunctions.InputVariable; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.OutputVariable; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; @@ -518,7 +518,7 @@ private static KernelFunction buildKernelFunction( try { Method method = OpenAPIHttpRequestPlugin.class.getMethod("execute", - KernelFunctionArguments.class); + KernelArguments.class); return KernelFunction .createFromMethod(method, plugin) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java index 57e461656..cf38760f0 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java @@ -9,7 +9,7 @@ import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.AIService; import com.microsoft.semantickernel.services.AIServiceCollection; import com.microsoft.semantickernel.services.AIServiceSelection; @@ -173,7 +173,7 @@ public FunctionInvocation invokePromptAsync(@Nonnull String prompt) { * @see KernelFunction#invokeAsync(Kernel) */ public FunctionInvocation invokePromptAsync(@Nonnull String prompt, - @Nonnull KernelFunctionArguments arguments) { + @Nonnull KernelArguments arguments) { KernelFunction function = KernelFunction.createFromPrompt(prompt).build(); return function.invokeAsync(this) @@ -192,7 +192,7 @@ public FunctionInvocation invokePromptAsync(@Nonnull String prompt, */ public FunctionInvocation invokePromptAsync(@Nonnull String prompt, - @Nonnull KernelFunctionArguments arguments, @Nonnull InvocationContext invocationContext) { + @Nonnull KernelArguments arguments, @Nonnull InvocationContext invocationContext) { KernelFunction function = KernelFunction.createFromPrompt(prompt).build(); @@ -278,7 +278,7 @@ public List> getFunctions() { * addition to any hooks provided to a function. * * @return The {@code KernelHooks} used throughout the kernel. - * @see KernelFunction#invokeAsync(Kernel, KernelFunctionArguments, ContextVariableType, + * @see KernelFunction#invokeAsync(Kernel, KernelArguments, ContextVariableType, * InvocationContext) */ @SuppressFBWarnings("EI_EXPOSE_REP") @@ -303,7 +303,7 @@ public AIServiceSelector getServiceSelector() { * @return The service of the specified type from the kernel. * @throws ServiceNotFoundException if the service is not found. * @see com.microsoft.semantickernel.services.AIServiceSelector#trySelectAIService(Class, - * KernelFunction, com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments) + * KernelFunction, KernelArguments) */ public T getService(Class clazz) throws ServiceNotFoundException { AIServiceSelection selector = serviceSelector diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokedEvent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokedEvent.java index 8f2d7eed8..7a39cdfe8 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokedEvent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokedEvent.java @@ -3,7 +3,7 @@ import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nullable; @@ -16,7 +16,7 @@ public class FunctionInvokedEvent implements KernelHookEvent { private final KernelFunction function; @Nullable - private final KernelFunctionArguments arguments; + private final KernelArguments arguments; private final FunctionResult result; /** @@ -28,10 +28,10 @@ public class FunctionInvokedEvent implements KernelHookEvent { */ public FunctionInvokedEvent( KernelFunction function, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, FunctionResult result) { this.function = function; - this.arguments = KernelFunctionArguments.builder().withVariables(arguments).build(); + this.arguments = KernelArguments.builder().withVariables(arguments).build(); this.result = result; } @@ -51,7 +51,7 @@ public KernelFunction getFunction() { */ @SuppressFBWarnings("EI_EXPOSE_REP") @Nullable - public KernelFunctionArguments getArguments() { + public KernelArguments getArguments() { return arguments; } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokingEvent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokingEvent.java index ab765cabe..ca360a760 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokingEvent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/FunctionInvokingEvent.java @@ -2,7 +2,7 @@ package com.microsoft.semantickernel.hooks; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nullable; @@ -16,7 +16,7 @@ public class FunctionInvokingEvent implements KernelHookEvent { private final KernelFunction function; - private final KernelFunctionArguments arguments; + private final KernelArguments arguments; /** * Creates a new instance of the FunctionInvokingEvent class. @@ -25,9 +25,9 @@ public class FunctionInvokingEvent implements KernelHookEvent { * @param arguments The arguments that are being passed to the function */ public FunctionInvokingEvent(KernelFunction function, - @Nullable KernelFunctionArguments arguments) { + @Nullable KernelArguments arguments) { this.function = function; - this.arguments = KernelFunctionArguments.builder().withVariables(arguments).build(); + this.arguments = KernelArguments.builder().withVariables(arguments).build(); } /** @@ -45,7 +45,7 @@ public KernelFunction getFunction() { * @return the arguments */ @SuppressFBWarnings("EI_EXPOSE_REP") - public KernelFunctionArguments getArguments() { + public KernelArguments getArguments() { return arguments; } } \ No newline at end of file diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PreToolCallEvent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PreToolCallEvent.java index c991efca1..42430f085 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PreToolCallEvent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PreToolCallEvent.java @@ -3,7 +3,7 @@ import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nullable; @@ -15,7 +15,7 @@ public class PreToolCallEvent implements KernelHookEvent { private final ContextVariableTypes contextVariableTypes; private final String functionName; @Nullable - private final KernelFunctionArguments arguments; + private final KernelArguments arguments; private final KernelFunction function; /** @@ -29,7 +29,7 @@ public class PreToolCallEvent implements KernelHookEvent { @SuppressFBWarnings("EI_EXPOSE_REP2") public PreToolCallEvent( String functionName, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, KernelFunction function, ContextVariableTypes contextVariableTypes) { this.functionName = functionName; @@ -44,7 +44,7 @@ public PreToolCallEvent( */ @SuppressFBWarnings("EI_EXPOSE_REP") @Nullable - public KernelFunctionArguments getArguments() { + public KernelArguments getArguments() { return arguments; } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderedEvent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderedEvent.java index f3f349725..348d3bf12 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderedEvent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderedEvent.java @@ -2,7 +2,7 @@ package com.microsoft.semantickernel.hooks; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nullable; @@ -12,7 +12,7 @@ public class PromptRenderedEvent implements KernelHookEvent { private final KernelFunction function; - private final KernelFunctionArguments arguments; + private final KernelArguments arguments; private final String prompt; /** @@ -24,10 +24,10 @@ public class PromptRenderedEvent implements KernelHookEvent { */ public PromptRenderedEvent( KernelFunction function, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, String prompt) { this.function = function; - this.arguments = KernelFunctionArguments.builder().withVariables(arguments).build(); + this.arguments = KernelArguments.builder().withVariables(arguments).build(); this.prompt = prompt; } @@ -46,7 +46,7 @@ public KernelFunction getFunction() { * @return the arguments */ @SuppressFBWarnings("EI_EXPOSE_REP") - public KernelFunctionArguments getArguments() { + public KernelArguments getArguments() { return arguments; } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderingEvent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderingEvent.java index 7bba17a38..fe9c54459 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderingEvent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/hooks/PromptRenderingEvent.java @@ -2,7 +2,7 @@ package com.microsoft.semantickernel.hooks; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nullable; @@ -12,7 +12,7 @@ public class PromptRenderingEvent implements KernelHookEvent { private final KernelFunction function; - private final KernelFunctionArguments arguments; + private final KernelArguments arguments; /** * Creates a new instance of the {@link PromptRenderingEvent} class. @@ -21,9 +21,9 @@ public class PromptRenderingEvent implements KernelHookEvent { * @param arguments the arguments */ public PromptRenderingEvent(KernelFunction function, - @Nullable KernelFunctionArguments arguments) { + @Nullable KernelArguments arguments) { this.function = function; - this.arguments = KernelFunctionArguments.builder().withVariables(arguments).build(); + this.arguments = KernelArguments.builder().withVariables(arguments).build(); } /** @@ -41,7 +41,7 @@ public KernelFunction getFunction() { * @return the arguments */ @SuppressFBWarnings("EI_EXPOSE_REP") - public KernelFunctionArguments getArguments() { + public KernelArguments getArguments() { return arguments; } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/telemetry/FunctionSpan.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/telemetry/FunctionSpan.java index 601b41305..72cc02609 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/telemetry/FunctionSpan.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/telemetry/FunctionSpan.java @@ -2,7 +2,7 @@ package com.microsoft.semantickernel.implementation.telemetry; import com.microsoft.semantickernel.orchestration.FunctionResult; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.SpanKind; @@ -27,7 +27,7 @@ public static FunctionSpan build( ContextView contextView, String pluginName, String name, - KernelFunctionArguments arguments) { + KernelArguments arguments) { SpanBuilder builder = telemetry.spanBuilder( String.format("function_invocation %s-%s", pluginName, name)) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/DefaultPromptTemplate.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/DefaultPromptTemplate.java index d0b70083a..15b80a662 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/DefaultPromptTemplate.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/DefaultPromptTemplate.java @@ -13,7 +13,7 @@ import com.microsoft.semantickernel.implementation.templateengine.tokenizer.blocks.VarBlock; import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.semanticfunctions.InputVariable; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.templateengine.semantickernel.TemplateException; @@ -137,7 +137,7 @@ private static PromptTemplateConfig addMissingInputVariables( @Override public Mono renderAsync( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable InvocationContext context) { ContextVariableTypes types; diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/CodeBlock.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/CodeBlock.java index e294c9251..cd6fffaad 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/CodeBlock.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/CodeBlock.java @@ -9,7 +9,7 @@ import com.microsoft.semantickernel.localization.SemanticKernelResources; import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.orchestration.InvocationContext; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionMetadata; import com.microsoft.semantickernel.templateengine.semantickernel.TemplateException; import com.microsoft.semantickernel.templateengine.semantickernel.TemplateException.ErrorCodes; @@ -97,7 +97,7 @@ private boolean isValidFunctionCall() { @Override public Mono renderCodeAsync( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable InvocationContext context) { if (!this.isValid()) { throw new TemplateException(ErrorCodes.SYNTAX_ERROR); @@ -136,7 +136,7 @@ public Mono renderCodeAsync( private Mono> renderFunctionCallAsync( FunctionIdBlock fBlock, Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, InvocationContext context, ContextVariableType resultType) { @@ -145,7 +145,7 @@ private Mono> renderFunctionCallAsync( if (this.tokens.size() > 1) { //Cloning the original arguments to avoid side effects - arguments added to the original arguments collection as a result of rendering template variables. arguments = this.enrichFunctionArguments(kernel, fBlock, - KernelFunctionArguments.builder().withVariables(arguments).build(), + KernelArguments.builder().withVariables(arguments).build(), context); } @@ -168,10 +168,10 @@ private Mono> renderFunctionCallAsync( /// The prompt rendering arguments. /// The function arguments. /// Occurs when any argument other than the first is not a named argument. - private KernelFunctionArguments enrichFunctionArguments( + private KernelArguments enrichFunctionArguments( Kernel kernel, FunctionIdBlock fBlock, - KernelFunctionArguments arguments, + KernelArguments arguments, @Nullable InvocationContext context) { Block firstArg = this.tokens.get(1); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/CodeRendering.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/CodeRendering.java index 7a411a095..673bcf68a 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/CodeRendering.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/CodeRendering.java @@ -3,7 +3,7 @@ import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.orchestration.InvocationContext; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import javax.annotation.Nullable; import reactor.core.publisher.Mono; @@ -24,6 +24,6 @@ public interface CodeRendering { */ Mono renderCodeAsync( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable InvocationContext context); } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/FunctionIdBlock.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/FunctionIdBlock.java index 58f8f5346..69e5a63be 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/FunctionIdBlock.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/FunctionIdBlock.java @@ -2,7 +2,7 @@ package com.microsoft.semantickernel.implementation.templateengine.tokenizer.blocks; import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import javax.annotation.Nullable; /** @@ -49,7 +49,7 @@ private static boolean hasMoreThanOneDot(String value) { @Override @Nullable - public String render(ContextVariableTypes types, @Nullable KernelFunctionArguments variables) { + public String render(ContextVariableTypes types, @Nullable KernelArguments variables) { return this.getContent(); } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/NamedArgBlock.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/NamedArgBlock.java index 010ba44e1..bed795020 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/NamedArgBlock.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/NamedArgBlock.java @@ -7,7 +7,7 @@ import com.microsoft.semantickernel.exceptions.SKException; import com.microsoft.semantickernel.implementation.Verify; import com.microsoft.semantickernel.localization.SemanticKernelResources; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import javax.annotation.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -132,7 +132,7 @@ public boolean isValid() { } @Override - public String render(ContextVariableTypes types, @Nullable KernelFunctionArguments variables) { + public String render(ContextVariableTypes types, @Nullable KernelArguments variables) { return getContent(); } @@ -155,7 +155,7 @@ public String getName() { } @SuppressWarnings("NullAway") - public String getValue(ContextVariableTypes types, KernelFunctionArguments arguments) { + public String getValue(ContextVariableTypes types, KernelArguments arguments) { boolean valueIsValidValBlock = this.valBlock != null && this.valBlock.isValid(); if (valueIsValidValBlock) { return this.valBlock.render(types, arguments); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/TextBlock.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/TextBlock.java index 3b7d1c09c..38128538e 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/TextBlock.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/TextBlock.java @@ -2,7 +2,7 @@ package com.microsoft.semantickernel.implementation.templateengine.tokenizer.blocks; import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import javax.annotation.Nullable; public final class TextBlock extends Block implements TextRendering { @@ -21,7 +21,7 @@ public boolean isValid() { } @Override - public String render(ContextVariableTypes types, @Nullable KernelFunctionArguments variables) { + public String render(ContextVariableTypes types, @Nullable KernelArguments variables) { return super.getContent(); } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/TextRendering.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/TextRendering.java index 751190742..184b4ca45 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/TextRendering.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/TextRendering.java @@ -2,7 +2,7 @@ package com.microsoft.semantickernel.implementation.templateengine.tokenizer.blocks; import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import javax.annotation.Nullable; /** @@ -17,5 +17,5 @@ public interface TextRendering { * @return Rendered content */ @Nullable - String render(ContextVariableTypes types, @Nullable KernelFunctionArguments variables); + String render(ContextVariableTypes types, @Nullable KernelArguments variables); } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/ValBlock.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/ValBlock.java index 3d647840f..d81c84b9a 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/ValBlock.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/ValBlock.java @@ -3,7 +3,7 @@ import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.localization.SemanticKernelResources; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import reactor.util.annotation.Nullable; @@ -41,7 +41,7 @@ public static boolean hasValPrefix(@Nullable String text) { @Override @Nullable - public String render(ContextVariableTypes types, @Nullable KernelFunctionArguments variables) { + public String render(ContextVariableTypes types, @Nullable KernelArguments variables) { return value; } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/VarBlock.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/VarBlock.java index 1aec228c3..5ae70bb32 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/VarBlock.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/implementation/templateengine/tokenizer/blocks/VarBlock.java @@ -4,7 +4,7 @@ import com.microsoft.semantickernel.contextvariables.ContextVariable; import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.localization.SemanticKernelResources; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.templateengine.semantickernel.TemplateException; import javax.annotation.Nullable; import org.slf4j.Logger; @@ -26,7 +26,7 @@ public VarBlock(String content) { } @Override - public String render(ContextVariableTypes types, @Nullable KernelFunctionArguments variables) { + public String render(ContextVariableTypes types, @Nullable KernelArguments variables) { if (variables == null) { return ""; } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java index 435d8538f..0ae16e194 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java @@ -14,7 +14,7 @@ import com.microsoft.semantickernel.implementation.telemetry.SemanticKernelTelemetry; import com.microsoft.semantickernel.localization.SemanticKernelResources; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.NoSuchElementException; import java.util.function.BiConsumer; @@ -41,7 +41,7 @@ public class FunctionInvocation extends Mono> { protected final ContextVariableType resultType; protected final ContextVariableTypes contextVariableTypes = new ContextVariableTypes(); @Nullable - protected KernelFunctionArguments arguments; + protected KernelArguments arguments; @Nullable protected UnmodifiableKernelHooks hooks; @Nullable @@ -95,7 +95,7 @@ private static void performSubscribe( CoreSubscriber> coreSubscriber, Kernel kernel, KernelFunction function, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable ContextVariableType variableType, @Nullable InvocationContext context) { if (variableType == null) { @@ -111,7 +111,7 @@ private static void performSubscribe( function .invokeAsync( kernel, - KernelFunctionArguments + KernelArguments .builder() .withVariables(arguments) .build(), @@ -174,9 +174,9 @@ private static UnmodifiableKernelHooks unmodifiableClone( * @return this {@code FunctionInvocation} for fluent chaining. */ public FunctionInvocation withArguments( - @Nullable KernelFunctionArguments arguments) { + @Nullable KernelArguments arguments) { logSubscribeWarning(); - this.arguments = KernelFunctionArguments.builder().withVariables(arguments).build(); + this.arguments = KernelArguments.builder().withVariables(arguments).build(); return this; } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java new file mode 100644 index 000000000..b81005517 --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java @@ -0,0 +1,410 @@ +// Copyright (c) Microsoft. All rights reserved. +package com.microsoft.semantickernel.semanticfunctions; + +import com.microsoft.semantickernel.builders.SemanticKernelBuilder; +import com.microsoft.semantickernel.contextvariables.CaseInsensitiveMap; +import com.microsoft.semantickernel.contextvariables.ContextVariable; +import com.microsoft.semantickernel.contextvariables.ContextVariableType; +import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter; +import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; +import com.microsoft.semantickernel.exceptions.SKException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; +import reactor.util.annotation.NonNull; + +/** + * Arguments to a kernel function. + */ +public class KernelArguments implements Map> { + + /** + * Default key for the main input. + */ + public static final String MAIN_KEY = "input"; + + protected final CaseInsensitiveMap> variables; + protected final Map promptExecutionSettings; + + /** + * Create a new instance of KernelArguments. + * + * @param variables The variables to use for the function invocation. + */ + protected KernelArguments( + @Nullable Map> variables, + @Nullable Map promptExecutionSettings) { + if (variables == null) { + this.variables = new CaseInsensitiveMap<>(); + } else { + this.variables = new CaseInsensitiveMap<>(variables); + } + + if (promptExecutionSettings == null) { + this.promptExecutionSettings = new HashMap<>(); + } else { + this.promptExecutionSettings = new HashMap<>(promptExecutionSettings); + } + } + + /** + * Create a new instance of KernelArguments. + * + * @param content The content to use for the function invocation. + */ + protected KernelArguments(@NonNull ContextVariable content) { + this.variables = new CaseInsensitiveMap<>(); + this.variables.put(MAIN_KEY, content); + + this.promptExecutionSettings = new HashMap<>(); + } + + /** + * Create a new instance of KernelArguments. + */ + protected KernelArguments() { + this.variables = new CaseInsensitiveMap<>(); + this.promptExecutionSettings = new HashMap<>(); + } + + /** + * Create a new instance of KernelArguments. + * + * @param arguments The arguments to copy. + */ + protected KernelArguments(@NonNull KernelArguments arguments) { + this.variables = new CaseInsensitiveMap<>(arguments.variables); + this.promptExecutionSettings = new HashMap<>(arguments.promptExecutionSettings); + } + + /** + * Get the prompt execution settings + * + * @return prompt execution settings + */ + @Nonnull + public Map getPromptExecutionSettings() { + return promptExecutionSettings; + } + + /** + * Get the input (entry in the MAIN_KEY slot) + * + * @return input + */ + @Nullable + public ContextVariable getInput() { + return get(MAIN_KEY); + } + + /** + * Create formatted string of the variables + * + * @return formatted string + */ + public String prettyPrint() { + return variables.entrySet().stream() + .reduce( + "", + (str, entry) -> str + + System.lineSeparator() + + entry.getKey() + + ": " + + entry.getValue().toPromptString(ContextVariableTypes.getGlobalTypes()), + (a, b) -> a + b); + } + + /** + * Return the variable with the given name + * + * @param key variable name + * @return content of the variable + */ + @Nullable + public ContextVariable get(String key) { + return variables.get(key); + } + + /** + * Return the variable with the given name + * + * @param key variable name + * @return content of the variable + */ + @Nullable + ContextVariable get(String key, Class clazz) { + ContextVariable value = variables.get(key); + if (value == null) { + return null; + } else if (clazz.isAssignableFrom(value.getType().getClazz())) { + return (ContextVariable) value; + } + + throw new SKException( + String.format( + "Variable %s is of type %s, but requested type is %s", + key, value.getType().getClazz(), clazz)); + } + + /** + * Return whether the variable with the given name is {@code null} or empty. + * + * @param key the key for the variable + * @return {@code true} if the variable is {@code null} or empty, {@code false} otherwise + */ + public boolean isNullOrEmpty(String key) { + return get(key) == null || get(key).isEmpty(); + } + + @Override + public int size() { + return variables.size(); + } + + @Override + public boolean isEmpty() { + return variables.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return variables.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return variables.containsValue(value); + } + + @Override + @Nullable + public ContextVariable get(Object key) { + return variables.get(key); + } + + @Override + public ContextVariable put(String key, ContextVariable value) { + return variables.put(key, value); + } + + @Override + public ContextVariable remove(Object key) { + return variables.remove(key); + } + + @Override + public void putAll(Map> m) { + variables.putAll(m); + } + + @Override + public void clear() { + variables.clear(); + } + + @Override + public Set keySet() { + return variables.keySet(); + } + + @Override + public Collection> values() { + return variables.values(); + } + + @Override + public Set>> entrySet() { + return variables.entrySet(); + } + + /** + * Create a copy of the current instance + * + * @return copy of the current instance + */ + public KernelArguments copy() { + return new KernelArguments(variables, promptExecutionSettings); + } + + /** + * Create a new instance of Builder. + * + * @return Builder + */ + public static Builder builder() { + return new Builder<>(KernelArguments::new); + } + + + /** + * Builder for ContextVariables + */ + public static class Builder implements SemanticKernelBuilder { + + private final Function constructor; + private final Map> variables; + private final Map promptExecutionSettings; + + + protected Builder(Function constructor) { + this.constructor = constructor; + this.variables = new HashMap<>(); + this.promptExecutionSettings = new HashMap<>(); + } + + /** + * Builds an instance with the given content in the default main key + * + * @param content Entry to place in the "input" slot + * @param Type of the value + * @return {$code this} Builder for fluent coding + */ + public Builder withInput(ContextVariable content) { + return withVariable(MAIN_KEY, content); + } + + /** + * Builds an instance with the given content in the default main key + * + * @param content Entry to place in the "input" slot + * @return {$code this} Builder for fluent coding + * @throws SKException if the content cannot be converted to a ContextVariable + */ + public Builder withInput(Object content) { + return withInput(ContextVariable.ofGlobalType(content)); + } + + /** + * Builds an instance with the given content in the default main key + * + * @param content Entry to place in the "input" slot + * @param typeConverter Type converter for the content + * @param Type of the value + * @return {$code this} Builder for fluent coding + * @throws SKException if the content cannot be converted to a ContextVariable + */ + public Builder withInput(T content, ContextVariableTypeConverter typeConverter) { + return withInput(new ContextVariable<>( + new ContextVariableType<>( + typeConverter, + typeConverter.getType()), + content)); + } + + /** + * Builds an instance with the given variables + * + * @param map Existing variables + * @return {$code this} Builder for fluent coding + */ + public Builder withVariables(@Nullable Map> map) { + if (map == null) { + return this; + } + variables.putAll(map); + return this; + } + + /** + * Set variable + * + * @param key variable name + * @param value variable value + * @param Type of the value + * @return {$code this} Builder for fluent coding + */ + public Builder withVariable(String key, ContextVariable value) { + variables.put(key, value); + return this; + } + + /** + * Set variable, uses the default type converters + * + * @param key variable name + * @param value variable value + * @return {$code this} Builder for fluent coding + * @throws SKException if the value cannot be converted to a ContextVariable + */ + public Builder withVariable(String key, Object value) { + if (value instanceof ContextVariable) { + return withVariable(key, (ContextVariable) value); + } + return withVariable(key, ContextVariable.ofGlobalType(value)); + } + + /** + * Set variable + * + * @param key variable name + * @param value variable value + * @param typeConverter Type converter for the value + * @param Type of the value + * @return {$code this} Builder for fluent coding + * @throws SKException if the value cannot be converted to a ContextVariable + */ + public Builder withVariable(String key, T value, + ContextVariableTypeConverter typeConverter) { + return withVariable(key, new ContextVariable<>( + new ContextVariableType<>( + typeConverter, + typeConverter.getType()), + value)); + } + + /** + * Set prompt execution settings + * + * @param promptExecutionSettings Prompt execution settings + * @return {$code this} Builder for fluent coding + */ + public Builder withPromptExecutionSettings(Map promptExecutionSettings) { + return withPromptExecutionSettings(new ArrayList<>(promptExecutionSettings.values())); + } + + /** + * Set prompt execution settings + * + * @param promptExecutionSettings Prompt execution settings + * @return {$code this} Builder for fluent coding + */ + public Builder withPromptExecutionSettings(List promptExecutionSettings) { + for (PromptExecutionSettings settings : promptExecutionSettings) { + String serviceId = settings.getServiceId(); + + if (this.promptExecutionSettings.containsKey(serviceId)) { + if (serviceId.equals(PromptExecutionSettings.DEFAULT_SERVICE_ID)) { + throw new SKException( + String.format( + "Multiple prompt execution settings with the default service id '%s' or no service id have been provided. Specify a single default prompt execution settings and provide a unique service id for all other instances.", + PromptExecutionSettings.DEFAULT_SERVICE_ID) + ); + } + + throw new SKException( + String.format( + "Multiple prompt execution settings with the service id '%s' have been provided. Specify a unique service id for all instances.", + serviceId) + ); + } + } + + return this; + } + + @Override + public U build() { + KernelArguments arguments = new KernelArguments(variables, promptExecutionSettings); + return constructor.apply(arguments); + } + } +} diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunction.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunction.java index 70f33bd75..742e84572 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunction.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunction.java @@ -189,7 +189,7 @@ public KernelFunctionMetadata getMetadata() { */ public abstract Mono> invokeAsync( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable ContextVariableType variableType, @Nullable InvocationContext invocationContext); @@ -221,7 +221,7 @@ public abstract Mono> invokeAsync( */ public FunctionResult invoke( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable ContextVariableType variableType, @Nullable InvocationContext invocationContext) { return invokeAsync(kernel, arguments, variableType, invocationContext).block(); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionArguments.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionArguments.java index f3b46c21a..76936cf23 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionArguments.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionArguments.java @@ -17,16 +17,17 @@ /** * Arguments to a kernel function. + * + * @deprecated Use {@link KernelArguments} instead. */ -public class KernelFunctionArguments implements Map> { +@Deprecated +public class KernelFunctionArguments extends KernelArguments { /** * Default key for the main input. */ public static final String MAIN_KEY = "input"; - private final CaseInsensitiveMap> variables; - /** * Create a new instance of KernelFunctionArguments. * @@ -34,11 +35,7 @@ public class KernelFunctionArguments implements Map> */ protected KernelFunctionArguments( @Nullable Map> variables) { - if (variables == null) { - this.variables = new CaseInsensitiveMap<>(); - } else { - this.variables = new CaseInsensitiveMap<>(variables); - } + super(variables, null); } /** @@ -47,15 +44,23 @@ protected KernelFunctionArguments( * @param content The content to use for the function invocation. */ protected KernelFunctionArguments(@NonNull ContextVariable content) { - this.variables = new CaseInsensitiveMap<>(); - this.variables.put(MAIN_KEY, content); + super(content); + } + + /** + * Create a new instance of KernelArguments. + * + * @param arguments The arguments to copy. + */ + protected KernelFunctionArguments(@NonNull KernelArguments arguments) { + super(arguments); } /** * Create a new instance of KernelFunctionArguments. */ protected KernelFunctionArguments() { - this.variables = new CaseInsensitiveMap<>(); + super(); } /** @@ -208,121 +213,18 @@ public KernelFunctionArguments copy() { /** * Builder for ContextVariables + * + * @deprecated Use {@link KernelArguments} builder instead. */ - public static class Builder implements SemanticKernelBuilder { - - private final Map> variables; + @Deprecated + public static class Builder extends KernelArguments.Builder { /** * Create a new instance of Builder. */ + @Deprecated public Builder() { - variables = new HashMap<>(); - } - - /** - * Builds an instance with the given content in the default main key - * - * @param content Entry to place in the "input" slot - * @param Type of the value - * @return {$code this} Builder for fluent coding - */ - public Builder withInput(ContextVariable content) { - return withVariable(MAIN_KEY, content); - } - - /** - * Builds an instance with the given content in the default main key - * - * @param content Entry to place in the "input" slot - * @return {$code this} Builder for fluent coding - * @throws SKException if the content cannot be converted to a ContextVariable - */ - public Builder withInput(Object content) { - return withInput(ContextVariable.ofGlobalType(content)); - } - - /** - * Builds an instance with the given content in the default main key - * - * @param content Entry to place in the "input" slot - * @param typeConverter Type converter for the content - * @param Type of the value - * @return {$code this} Builder for fluent coding - * @throws SKException if the content cannot be converted to a ContextVariable - */ - public Builder withInput(T content, ContextVariableTypeConverter typeConverter) { - return withInput(new ContextVariable<>( - new ContextVariableType<>( - typeConverter, - typeConverter.getType()), - content)); - } - - /** - * Builds an instance with the given variables - * - * @param map Existing variables - * @return {$code this} Builder for fluent coding - */ - public Builder withVariables(@Nullable Map> map) { - if (map == null) { - return this; - } - variables.putAll(map); - return this; - } - - /** - * Set variable - * - * @param key variable name - * @param value variable value - * @param Type of the value - * @return {$code this} Builder for fluent coding - */ - public Builder withVariable(String key, ContextVariable value) { - variables.put(key, value); - return this; - } - - /** - * Set variable, uses the default type converters - * - * @param key variable name - * @param value variable value - * @return {$code this} Builder for fluent coding - * @throws SKException if the value cannot be converted to a ContextVariable - */ - public Builder withVariable(String key, Object value) { - if (value instanceof ContextVariable) { - return withVariable(key, (ContextVariable) value); - } - return withVariable(key, ContextVariable.ofGlobalType(value)); - } - - /** - * Set variable - * - * @param key variable name - * @param value variable value - * @param typeConverter Type converter for the value - * @param Type of the value - * @return {$code this} Builder for fluent coding - * @throws SKException if the value cannot be converted to a ContextVariable - */ - public Builder withVariable(String key, T value, - ContextVariableTypeConverter typeConverter) { - return withVariable(key, new ContextVariable<>( - new ContextVariableType<>( - typeConverter, - typeConverter.getType()), - value)); - } - - @Override - public KernelFunctionArguments build() { - return new KernelFunctionArguments(variables); + super(KernelFunctionArguments::new); } } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java index afda500ae..6704255ff 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethod.java @@ -176,7 +176,7 @@ public static ImplementationFunc getFunction(Method method, Object instan FunctionInvokingEvent updatedState = kernelHooks .executeHooks( new FunctionInvokingEvent(function, arguments)); - KernelFunctionArguments updatedArguments = updatedState != null + KernelArguments updatedArguments = updatedState != null ? updatedState.getArguments() : arguments; @@ -344,11 +344,11 @@ private static Mono invokeAsyncFunction( @Nullable private static Function getParameters( Method method, - @Nullable KernelFunctionArguments context, + @Nullable KernelArguments context, Kernel kernel, InvocationContext invocationContext) { return parameter -> { - if (KernelFunctionArguments.class.isAssignableFrom(parameter.getType())) { + if (KernelArguments.class.isAssignableFrom(parameter.getType())) { return context; } else if (Kernel.class.isAssignableFrom(parameter.getType())) { return kernel; @@ -361,7 +361,7 @@ private static Function getParameters( @Nullable private static Object getArgumentValue( Method method, - @Nullable KernelFunctionArguments context, + @Nullable KernelArguments context, Parameter parameter, Kernel kernel, InvocationContext invocationContext) { @@ -525,15 +525,15 @@ private static Object toObjectType( @Nullable private static ContextVariable getVariableFromContext( Method method, - @Nullable KernelFunctionArguments context, + @Nullable KernelArguments context, String variableName) { ContextVariable variable = context == null ? null : context.get(variableName); // If there is 1 argument use "input" or the only argument if (variable == null && method.getParameters().length == 1) { if (context != null) { - if (context.containsKey(KernelFunctionArguments.MAIN_KEY)) { - variable = context.get(KernelFunctionArguments.MAIN_KEY); + if (context.containsKey(KernelArguments.MAIN_KEY)) { + variable = context.get(KernelArguments.MAIN_KEY); } else if (context.size() == 1) { variable = context.values().iterator().next(); } @@ -672,7 +672,7 @@ private static InputVariable toKernelParameterMetadata(Parameter parameter) { boolean isRequired = true; Class type = parameter.getType(); - if (Kernel.class.isAssignableFrom(type) || KernelFunctionArguments.class.isAssignableFrom( + if (Kernel.class.isAssignableFrom(type) || KernelArguments.class.isAssignableFrom( type)) { return null; } @@ -729,7 +729,7 @@ public static Builder builder() { @Override public Mono> invokeAsync( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable ContextVariableType variableType, @Nullable InvocationContext invocationContext) { @@ -770,7 +770,7 @@ public interface ImplementationFunc { Mono> invokeAsync( Kernel kernel, KernelFunction function, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable ContextVariableType variableType, @Nullable InvocationContext invocationContext); @@ -787,7 +787,7 @@ Mono> invokeAsync( default FunctionResult invoke( Kernel kernel, KernelFunction function, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable ContextVariableType variableType, @Nullable InvocationContext invocationContext) { return invokeAsync(kernel, function, arguments, variableType, diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java index 5c2c5412e..1d12f961b 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java @@ -98,7 +98,7 @@ public static Builder builder(Class returnType) { private Flux> invokeInternalAsync( Kernel kernel, - @Nullable KernelFunctionArguments argumentsIn, + @Nullable KernelArguments argumentsIn, @Nullable ContextVariableType contextVariableType, @Nullable InvocationContext invocationContext) { @@ -113,7 +113,7 @@ private Flux> invokeInternalAsync( PromptRenderingEvent preRenderingHookResult = kernelHooks .executeHooks(new PromptRenderingEvent(this, argumentsIn)); - KernelFunctionArguments arguments = preRenderingHookResult.getArguments(); + KernelArguments arguments = preRenderingHookResult.getArguments(); // TODO: put in method, add catch for classcastexception, fallback to noopconverter ContextVariableType variableType = contextVariableType != null @@ -127,7 +127,7 @@ private Flux> invokeInternalAsync( PromptRenderedEvent promptHookResult = kernelHooks .executeHooks(new PromptRenderedEvent(this, arguments, prompt)); prompt = promptHookResult.getPrompt(); - KernelFunctionArguments args = promptHookResult.getArguments(); + KernelArguments args = promptHookResult.getArguments(); LOGGER.info(SemanticKernelResources.getString("rendered.prompt"), prompt); @@ -273,7 +273,7 @@ private Flux> invokeInternalAsync( @Override public Mono> invokeAsync( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable ContextVariableType variableType, @Nullable InvocationContext invocationContext) { return Mono.deferContextual(contextView -> { diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplate.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplate.java index 04f0c6432..58a5c6a81 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplate.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplate.java @@ -24,7 +24,7 @@ public interface PromptTemplate { */ Mono renderAsync( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable InvocationContext context); } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java index 3255d79e0..c48fa475c 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java @@ -2,7 +2,7 @@ package com.microsoft.semantickernel.services; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import javax.annotation.Nullable; /** @@ -15,7 +15,7 @@ public interface AIServiceSelector { /** * Resolves an {@link AIService} and associated and * {@link com.microsoft.semantickernel.orchestration.PromptExecutionSettings} based on the - * associated {@link KernelFunction} and {@link KernelFunctionArguments}. + * associated {@link KernelFunction} and {@link KernelArguments}. * * @param serviceType The type of service to select. This must be the same type with which the * service was registered in the {@link AIServiceSelection} @@ -26,9 +26,10 @@ public interface AIServiceSelector { * @return An {@code AIServiceSelection} containing the selected service and associated * PromptExecutionSettings. */ +// @Deprecated @Nullable AIServiceSelection trySelectAIService( Class serviceType, @Nullable KernelFunction function, - @Nullable KernelFunctionArguments arguments); + @Nullable KernelArguments arguments); } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java index 2eaa9404c..c3e42b8e6 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java @@ -2,16 +2,16 @@ package com.microsoft.semantickernel.services; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import java.util.Map; import javax.annotation.Nullable; /** * Base class for {@link AIServiceSelector} implementations which provides a {@code Map} based * collection from which an {@link AIService} can be selected. The - * {@link #trySelectAIService(Class, KernelFunction, KernelFunctionArguments)} method has been + * {@link #trySelectAIService(Class, KernelFunction, KernelArguments)} method has been * implemented. Child classes must implement the method - * {@link #trySelectAIService(Class, KernelFunction, KernelFunctionArguments, Map)}. + * {@link #trySelectAIService(Class, KernelFunction, KernelArguments, Map)}. */ public abstract class BaseAIServiceSelector implements AIServiceSelector { @@ -31,7 +31,7 @@ protected BaseAIServiceSelector(AIServiceCollection services) { public AIServiceSelection trySelectAIService( Class serviceType, @Nullable KernelFunction function, - @Nullable KernelFunctionArguments arguments) { + @Nullable KernelArguments arguments) { return trySelectAIService(serviceType, function, arguments, services); } @@ -52,6 +52,6 @@ public AIServiceSelection trySelectAIService( protected abstract AIServiceSelection trySelectAIService( Class serviceType, @Nullable KernelFunction function, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, Map, AIService> services); } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java index 8e607cdb1..2be735439 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java @@ -5,7 +5,7 @@ import com.microsoft.semantickernel.localization.SemanticKernelResources; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.services.textcompletion.TextGenerationService; import java.util.List; @@ -66,18 +66,34 @@ private static Map settingsFromFunctionSettings return null; } +// @Nullable +// @Override +// public AIServiceSelection trySelectAIService( +// Class serviceType, +// @Nullable KernelArguments arguments) { +// return selectAIService(serviceType, arguments.getPromptExecutionSettings()); +// } + @Nullable @Override public AIServiceSelection trySelectAIService( Class serviceType, @Nullable KernelFunction function, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, Map, AIService> services) { // Allow the execution settings from the kernel arguments to take precedence Map executionSettings = settingsFromFunctionSettings( function); + return selectAIService(serviceType, executionSettings); + } + + + private AIServiceSelection selectAIService( + Class serviceType, + @Nullable Map executionSettings) { + if (executionSettings == null || executionSettings.isEmpty()) { AIService service = getAnyService(serviceType); if (service != null) { @@ -85,50 +101,50 @@ public AIServiceSelection trySelectAIService( } } else { AIServiceSelection selection = executionSettings - .entrySet() - .stream() - .map(keyValue -> { - - PromptExecutionSettings settings = keyValue.getValue(); - String serviceId = keyValue.getKey(); - - if (!Verify.isNullOrEmpty(serviceId)) { - AIService service = getService(serviceId); - if (service != null) { - return castServiceSelection( - new AIServiceSelection<>(service, settings)); + .entrySet() + .stream() + .map(keyValue -> { + + PromptExecutionSettings settings = keyValue.getValue(); + String serviceId = keyValue.getKey(); + + if (!Verify.isNullOrEmpty(serviceId)) { + AIService service = getService(serviceId); + if (service != null) { + return castServiceSelection( + new AIServiceSelection<>(service, settings)); + } } - } - return null; - }) - .filter(Objects::nonNull) - .findFirst() - .orElseGet(() -> null); + return null; + }) + .filter(Objects::nonNull) + .findFirst() + .orElseGet(() -> null); if (selection != null) { return castServiceSelection(selection); } selection = executionSettings - .entrySet() - .stream() - .map(keyValue -> { - PromptExecutionSettings settings = keyValue.getValue(); - - if (!Verify.isNullOrEmpty(settings.getModelId())) { - AIService service = getServiceByModelId(settings.getModelId()); - if (service != null) { - return castServiceSelection( - new AIServiceSelection<>(service, settings)); + .entrySet() + .stream() + .map(keyValue -> { + PromptExecutionSettings settings = keyValue.getValue(); + + if (!Verify.isNullOrEmpty(settings.getModelId())) { + AIService service = getServiceByModelId(settings.getModelId()); + if (service != null) { + return castServiceSelection( + new AIServiceSelection<>(service, settings)); + } } - } - return null; - }) - .filter(Objects::nonNull) - .findFirst() - .orElseGet(() -> null); + return null; + }) + .filter(Objects::nonNull) + .findFirst() + .orElseGet(() -> null); if (selection != null) { return castServiceSelection(selection); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java index aed37718d..460e48159 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplate.java @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.templateengine.handlebars; -import static com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments.MAIN_KEY; +import static com.microsoft.semantickernel.semanticfunctions.KernelArguments.MAIN_KEY; import com.github.jknack.handlebars.Context; import com.github.jknack.handlebars.EscapingStrategy; @@ -19,7 +19,7 @@ import com.microsoft.semantickernel.orchestration.ToolCallBehavior; import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateOption; @@ -59,7 +59,7 @@ public HandlebarsPromptTemplate( @Override public Mono renderAsync( Kernel kernel, - @Nullable KernelFunctionArguments arguments, + @Nullable KernelArguments arguments, @Nullable InvocationContext context) { String template = promptTemplate.getTemplate(); if (template == null) { @@ -75,7 +75,7 @@ public Mono renderAsync( template, context); if (arguments == null) { - arguments = KernelFunctionArguments.builder().build(); + arguments = KernelArguments.builder().build(); } return handler.render(arguments); } @@ -131,8 +131,8 @@ private static class ContextVariableResolver implements ValueResolver { public Object resolve(Object context, String name) { Object value = null; ContextVariable variable = null; - if (context instanceof KernelFunctionArguments) { - variable = ((KernelFunctionArguments) context).get(name); + if (context instanceof KernelArguments) { + variable = ((KernelArguments) context).get(name); } else if (context instanceof ContextVariable) { variable = ((ContextVariable) context); } @@ -174,9 +174,9 @@ private String promptString(ContextVariable context) { @Override public Set> propertySet(Object context) { - if (context instanceof KernelFunctionArguments) { + if (context instanceof KernelArguments) { HashMap result = new HashMap<>(); - result.putAll((KernelFunctionArguments) context); + result.putAll((KernelArguments) context); return result.entrySet(); } else if (context instanceof ContextVariable) { HashMap result = new HashMap<>(); @@ -270,7 +270,7 @@ private CharSequence handleMessage(Object context, Options options) return null; } - public Mono render(KernelFunctionArguments variables) { + public Mono render(KernelArguments variables) { try { ArrayList resolvers = new ArrayList<>(); resolvers.add(new MessageResolver()); @@ -319,9 +319,9 @@ private static Helper functionInvokeHelper( InvocationContext invocationContext) { return (context, options) -> { - KernelFunctionArguments.Builder builder = KernelFunctionArguments.builder(); - if (context instanceof KernelFunctionArguments) { - builder.withVariables((KernelFunctionArguments) context); + KernelArguments.Builder builder = KernelArguments.builder(); + if (context instanceof KernelArguments) { + builder.withVariables((KernelArguments) context); } else { builder.withInput(context); } diff --git a/semantickernel-api/src/test/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethodTest.java b/semantickernel-api/src/test/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethodTest.java index 589705f33..a2dae1370 100644 --- a/semantickernel-api/src/test/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethodTest.java +++ b/semantickernel-api/src/test/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromMethodTest.java @@ -52,7 +52,7 @@ void typeConversionOnMethodCall() { .invokeAsync(kernel) .withResultType(ContextVariableTypes.getGlobalVariableTypeForClass(String.class)) .withArguments( - KernelFunctionArguments.builder() + KernelArguments.builder() .withVariable("number1", "12.0") .build()) .block(); @@ -182,7 +182,7 @@ interface InvocationTest { Method getMethod() throws NoSuchMethodException; - KernelFunctionArguments getArguments(); + KernelArguments getArguments(); void assertCalled(); } @@ -203,8 +203,8 @@ public Method getMethod() throws NoSuchMethodException { } @Override - public KernelFunctionArguments getArguments() { - return KernelFunctionArguments.builder() + public KernelArguments getArguments() { + return KernelArguments.builder() .withVariable("i", 123) .build(); } @@ -232,8 +232,8 @@ public Method getMethod() throws NoSuchMethodException { } @Override - public KernelFunctionArguments getArguments() { - return KernelFunctionArguments.builder() + public KernelArguments getArguments() { + return KernelArguments.builder() .withVariable("i", 123) .build(); } @@ -261,8 +261,8 @@ public Method getMethod() throws NoSuchMethodException { } @Override - public KernelFunctionArguments getArguments() { - return KernelFunctionArguments.builder() + public KernelArguments getArguments() { + return KernelArguments.builder() .withVariable("i", 123) .build(); } @@ -290,8 +290,8 @@ public Method getMethod() throws NoSuchMethodException { } @Override - public KernelFunctionArguments getArguments() { - return KernelFunctionArguments.builder() + public KernelArguments getArguments() { + return KernelArguments.builder() .withVariable("i", Arrays.asList(1, 2, 3)) .build(); } @@ -319,8 +319,8 @@ public Method getMethod() throws NoSuchMethodException { } @Override - public KernelFunctionArguments getArguments() { - return KernelFunctionArguments.builder() + public KernelArguments getArguments() { + return KernelArguments.builder() .build(); } @@ -347,7 +347,7 @@ public Method getMethod() throws NoSuchMethodException { } @Override - public KernelFunctionArguments getArguments() { + public KernelArguments getArguments() { ContextVariableTypeConverter dbConverter = ContextVariableTypeConverter .builder(BigDecimal.class) @@ -355,7 +355,7 @@ public KernelFunctionArguments getArguments() { .toPromptString(i -> null) .build(); - return KernelFunctionArguments.builder() + return KernelArguments.builder() .withVariable("i", new BigDecimal(123), dbConverter) .build(); } @@ -401,14 +401,14 @@ public Method getMethod() throws NoSuchMethodException { } @Override - public KernelFunctionArguments getArguments() { + public KernelArguments getArguments() { ContextVariableTypeConverter sourceConverter = ContextVariableTypeConverter .builder(SourceClass.class) .fromObject(i -> (SourceClass) i) .toPromptString(i -> null) .build(); - return KernelFunctionArguments.builder() + return KernelArguments.builder() .withVariable("i", new SourceClass(123), sourceConverter) .build(); } diff --git a/semantickernel-api/src/test/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateFactoryTest.java b/semantickernel-api/src/test/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateFactoryTest.java index f386084e4..67e86d43d 100644 --- a/semantickernel-api/src/test/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateFactoryTest.java +++ b/semantickernel-api/src/test/java/com/microsoft/semantickernel/semanticfunctions/PromptTemplateFactoryTest.java @@ -93,7 +93,7 @@ private void executeTest(String templateFormat) throws Exception { PromptTemplate promptTemplate = PromptTemplateFactory.build(config); - KernelFunctionArguments args = KernelFunctionArguments.builder() + KernelArguments args = KernelArguments.builder() .withInput(ContextVariable.of("input from args")).build(); String expected = String.format("A template for testing: %s", diff --git a/semantickernel-api/src/test/java/com/microsoft/semantickernel/services/AIServiceSelectorTest.java b/semantickernel-api/src/test/java/com/microsoft/semantickernel/services/AIServiceSelectorTest.java index f9be46cdd..13ee076f1 100644 --- a/semantickernel-api/src/test/java/com/microsoft/semantickernel/services/AIServiceSelectorTest.java +++ b/semantickernel-api/src/test/java/com/microsoft/semantickernel/services/AIServiceSelectorTest.java @@ -8,7 +8,7 @@ import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import org.junit.jupiter.api.Test; @@ -185,7 +185,7 @@ public String getServiceId() { AIServiceSelection expected = new AIServiceSelection<>(aService, null); - KernelFunctionArguments arguments = KernelFunctionArguments.builder().build(); + KernelArguments arguments = KernelArguments.builder().build(); Kernel kernel = Kernel.builder() .withAIService((Class) aService.getClass(), aService) diff --git a/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplateTest.java b/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplateTest.java index 228d64dc7..3a31de30e 100644 --- a/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplateTest.java +++ b/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/handlebars/HandlebarsPromptTemplateTest.java @@ -13,7 +13,7 @@ import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.plugin.KernelPlugin; import com.microsoft.semantickernel.plugin.KernelPluginFactory; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; @@ -97,7 +97,7 @@ void testRenderAsync() { HandlebarsPromptTemplate instance = new HandlebarsPromptTemplate(promptTemplate); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withVariable("input", "Hello ") .withVariable("suffix", "World") .withVariable("choices", choices) @@ -146,7 +146,7 @@ public void testSerializesObject() { HandlebarsPromptTemplate instance = new HandlebarsPromptTemplate(promptTemplate); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withVariable("input", new Foo("bar"), ContextVariableJacksonConverter.create(Foo.class)) .build(); @@ -171,7 +171,7 @@ public void testMessageContent() { HandlebarsPromptTemplate instance = new HandlebarsPromptTemplate(promptTemplate); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withVariable("input", new ChatHistory() .addAssistantMessage("foo") .addUserMessage("bar\"<>&")) @@ -196,7 +196,7 @@ public void testMessageHandler() { HandlebarsPromptTemplate instance = new HandlebarsPromptTemplate(promptTemplate); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withVariable("input", "bar\"<>&") .build(); @@ -220,7 +220,7 @@ public void iterableWithContextVariable() { HandlebarsPromptTemplate instance = new HandlebarsPromptTemplate(promptTemplate); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withVariable("input", Arrays.asList(ContextVariable.of("foo\"<>&"))) .build(); @@ -245,7 +245,7 @@ public void withCustomConverter() { Foo.class) .toPromptString(Foo::getVal) .build(); - KernelFunctionArguments arguments = KernelFunctionArguments.builder() + KernelArguments arguments = KernelArguments.builder() .withVariable("input", ContextVariable.of(new Foo("bar\"<>&"), converter)) .build(); diff --git a/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizerTest.java b/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizerTest.java index 8a491680c..d39c6aaff 100644 --- a/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizerTest.java +++ b/semantickernel-api/src/test/java/com/microsoft/semantickernel/templateengine/semantickernel/CodeTokenizerTest.java @@ -6,7 +6,7 @@ import com.microsoft.semantickernel.implementation.templateengine.tokenizer.blocks.Block; import com.microsoft.semantickernel.implementation.templateengine.tokenizer.blocks.FunctionIdBlock; import com.microsoft.semantickernel.implementation.templateengine.tokenizer.blocks.NamedArgBlock; -import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -28,7 +28,7 @@ public void parseNamedArgs1() { Assertions.assertEquals("street", namedArgBlock.getName()); Assertions.assertEquals("123 Main St", namedArgBlock.getValue( new ContextVariableTypes(), - new KernelFunctionArguments.Builder() + KernelArguments.builder() .withVariable("street", "123 Main St") .build())); @@ -36,13 +36,13 @@ public void parseNamedArgs1() { Assertions.assertEquals("zip", namedArgBlock.getName()); Assertions.assertEquals("98123", namedArgBlock.getValue( new ContextVariableTypes(), - new KernelFunctionArguments.Builder().build())); + KernelArguments.builder().build())); namedArgBlock = (NamedArgBlock) tokens.get(3); Assertions.assertEquals("city", namedArgBlock.getName()); Assertions.assertEquals("Seattle", namedArgBlock.getValue( new ContextVariableTypes(), - new KernelFunctionArguments.Builder().build())); + KernelArguments.builder().build())); } @Test @@ -60,7 +60,6 @@ public void parseNamedArgs2() { Assertions.assertEquals("recall", namedArgBlock.getName()); Assertions.assertEquals("where did I grow up?", namedArgBlock.getValue( new ContextVariableTypes(), - new KernelFunctionArguments.Builder() - .build())); + KernelArguments.builder().build())); } } From b378f634ddbebf9ab5aec6baa6e793401d4563f3 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 14 Apr 2025 23:45:22 -0700 Subject: [PATCH 07/46] Update --- .../samples/syntaxexamples/Example61_MultipleLLMs.java | 7 ++++--- .../semantickernel/semanticfunctions/KernelArguments.java | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example61_MultipleLLMs.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example61_MultipleLLMs.java index 8348ee517..0396d575f 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example61_MultipleLLMs.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/Example61_MultipleLLMs.java @@ -9,6 +9,7 @@ import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionArguments; import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; @@ -73,7 +74,7 @@ public static void runByServiceIdAsync(Kernel kernel, String serviceId) { var prompt = "Hello AI, what can you do for me?"; - KernelFunctionArguments arguments = KernelFunctionArguments.builder().build(); + KernelArguments arguments = KernelArguments.builder().build(); KernelFunction func = KernelFunctionFromPrompt .builder() @@ -104,7 +105,7 @@ public static void runByModelIdAsync(Kernel kernel, String modelId) { .build()) .withOutputVariable("result", "java.lang.String") .build()) - .withArguments(KernelFunctionArguments.builder().build()) + .withArguments(KernelArguments.builder().build()) .block(); System.out.println(result.getResult()); @@ -136,7 +137,7 @@ public static void runByFirstModelIdAsync(Kernel kernel, String... modelIds) { .build(); var result = kernel.invokeAsync(function) - .withArguments(KernelFunctionArguments.builder().build()) + .withArguments(KernelArguments.builder().build()) .block(); System.out.println(result.getResult()); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java index b81005517..5b41afc9b 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -93,7 +94,7 @@ protected KernelArguments(@NonNull KernelArguments arguments) { */ @Nonnull public Map getPromptExecutionSettings() { - return promptExecutionSettings; + return Collections.unmodifiableMap(promptExecutionSettings); } /** From c788b1ce7014cc0418e81a42eb95d3e1c88008a2 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 14 Apr 2025 23:52:11 -0700 Subject: [PATCH 08/46] Update --- .../samples/plugins/ConversationSummaryPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java index 1bd163711..0a224c2fd 100644 --- a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java +++ b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/ConversationSummaryPlugin.java @@ -71,7 +71,7 @@ private static Mono processAsync(KernelFunction func, String inp // The first parameter is the input text. return func.invokeAsync(kernel) .withArguments( - new KernelArguments.Builder() + KernelArguments.builder() .withInput(paragraph) .build()) .withResultType( From c98c39ac3147941aace5e3d6841241e30a81d84c Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Tue, 15 Apr 2025 11:44:38 -0700 Subject: [PATCH 09/46] Remove comment --- .../com/microsoft/semantickernel/services/AIServiceSelector.java | 1 - 1 file changed, 1 deletion(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java index c48fa475c..e68e6a696 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java @@ -26,7 +26,6 @@ public interface AIServiceSelector { * @return An {@code AIServiceSelection} containing the selected service and associated * PromptExecutionSettings. */ -// @Deprecated @Nullable AIServiceSelection trySelectAIService( Class serviceType, From 7620749f7e912f8581762f9eebf60334d80eeaed Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Tue, 15 Apr 2025 16:53:04 -0700 Subject: [PATCH 10/46] Rename field to executionSettings to match old class field name --- .../semanticfunctions/KernelArguments.java | 48 ++++++++++--------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java index 5b41afc9b..80ec59727 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java @@ -34,7 +34,7 @@ public class KernelArguments implements Map> { public static final String MAIN_KEY = "input"; protected final CaseInsensitiveMap> variables; - protected final Map promptExecutionSettings; + protected final Map executionSettings; /** * Create a new instance of KernelArguments. @@ -43,17 +43,17 @@ public class KernelArguments implements Map> { */ protected KernelArguments( @Nullable Map> variables, - @Nullable Map promptExecutionSettings) { + @Nullable Map executionSettings) { if (variables == null) { this.variables = new CaseInsensitiveMap<>(); } else { this.variables = new CaseInsensitiveMap<>(variables); } - if (promptExecutionSettings == null) { - this.promptExecutionSettings = new HashMap<>(); + if (executionSettings == null) { + this.executionSettings = new HashMap<>(); } else { - this.promptExecutionSettings = new HashMap<>(promptExecutionSettings); + this.executionSettings = new HashMap<>(executionSettings); } } @@ -63,10 +63,8 @@ protected KernelArguments( * @param content The content to use for the function invocation. */ protected KernelArguments(@NonNull ContextVariable content) { - this.variables = new CaseInsensitiveMap<>(); + this(); this.variables.put(MAIN_KEY, content); - - this.promptExecutionSettings = new HashMap<>(); } /** @@ -74,7 +72,7 @@ protected KernelArguments(@NonNull ContextVariable content) { */ protected KernelArguments() { this.variables = new CaseInsensitiveMap<>(); - this.promptExecutionSettings = new HashMap<>(); + this.executionSettings = new HashMap<>(); } /** @@ -84,7 +82,7 @@ protected KernelArguments() { */ protected KernelArguments(@NonNull KernelArguments arguments) { this.variables = new CaseInsensitiveMap<>(arguments.variables); - this.promptExecutionSettings = new HashMap<>(arguments.promptExecutionSettings); + this.executionSettings = new HashMap<>(arguments.executionSettings); } /** @@ -93,8 +91,8 @@ protected KernelArguments(@NonNull KernelArguments arguments) { * @return prompt execution settings */ @Nonnull - public Map getPromptExecutionSettings() { - return Collections.unmodifiableMap(promptExecutionSettings); + public Map getExecutionSettings() { + return Collections.unmodifiableMap(executionSettings); } /** @@ -233,7 +231,7 @@ public Set>> entrySet() { * @return copy of the current instance */ public KernelArguments copy() { - return new KernelArguments(variables, promptExecutionSettings); + return new KernelArguments(variables, executionSettings); } /** @@ -253,13 +251,13 @@ public static class Builder implements SemanticKernel private final Function constructor; private final Map> variables; - private final Map promptExecutionSettings; + private final Map executionSettings; protected Builder(Function constructor) { this.constructor = constructor; this.variables = new HashMap<>(); - this.promptExecutionSettings = new HashMap<>(); + this.executionSettings = new HashMap<>(); } /** @@ -365,24 +363,28 @@ public Builder withVariable(String key, T value, /** * Set prompt execution settings * - * @param promptExecutionSettings Prompt execution settings + * @param executionSettings Execution settings * @return {$code this} Builder for fluent coding */ - public Builder withPromptExecutionSettings(Map promptExecutionSettings) { - return withPromptExecutionSettings(new ArrayList<>(promptExecutionSettings.values())); + public Builder withExecutionSettings(Map executionSettings) { + return withExecutionSettings(new ArrayList<>(executionSettings.values())); } /** * Set prompt execution settings * - * @param promptExecutionSettings Prompt execution settings + * @param executionSettings Execution settings * @return {$code this} Builder for fluent coding */ - public Builder withPromptExecutionSettings(List promptExecutionSettings) { - for (PromptExecutionSettings settings : promptExecutionSettings) { + public Builder withExecutionSettings(List executionSettings) { + if (executionSettings == null) { + return this; + } + + for (PromptExecutionSettings settings : executionSettings) { String serviceId = settings.getServiceId(); - if (this.promptExecutionSettings.containsKey(serviceId)) { + if (this.executionSettings.containsKey(serviceId)) { if (serviceId.equals(PromptExecutionSettings.DEFAULT_SERVICE_ID)) { throw new SKException( String.format( @@ -404,7 +406,7 @@ public Builder withPromptExecutionSettings(List prom @Override public U build() { - KernelArguments arguments = new KernelArguments(variables, promptExecutionSettings); + KernelArguments arguments = new KernelArguments(variables, executionSettings); return constructor.apply(arguments); } } From 44b27cdf1c1af071ec2eba2ca30f0d48621afc80 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 17 Apr 2025 09:00:39 -0700 Subject: [PATCH 11/46] Add AIServiceSelector.trySelectAIService(Class,KernelArguments) and related updates --- .../com/microsoft/semantickernel/Kernel.java | 27 +++++++++++++-- .../semanticfunctions/KernelArguments.java | 10 ++++++ .../KernelFunctionFromPrompt.java | 8 +++-- .../services/AIServiceSelector.java | 26 ++++++++++++++- .../services/BaseAIServiceSelector.java | 33 +++++++++++++++++++ .../services/OrderedAIServiceSelector.java | 16 +++++---- 6 files changed, 107 insertions(+), 13 deletions(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java index cf38760f0..d8059ef78 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java @@ -302,14 +302,12 @@ public AIServiceSelector getServiceSelector() { * @param clazz The class of the service to get. * @return The service of the specified type from the kernel. * @throws ServiceNotFoundException if the service is not found. - * @see com.microsoft.semantickernel.services.AIServiceSelector#trySelectAIService(Class, - * KernelFunction, KernelArguments) + * @see com.microsoft.semantickernel.services.AIServiceSelector#trySelectAIService(Class, KernelArguments) */ public T getService(Class clazz) throws ServiceNotFoundException { AIServiceSelection selector = serviceSelector .trySelectAIService( clazz, - null, null); if (selector == null) { @@ -319,6 +317,29 @@ public T getService(Class clazz) throws ServiceNotFound return selector.getService(); } + /** + * Get the service of the specified type from the kernel. + * + * @param The type of the service to get. + * @param clazz The class of the service to get. + * @param args The arguments to help select the service to get. + * @return The service of the specified type from the kernel. + * @throws ServiceNotFoundException if the service is not found. + * @see com.microsoft.semantickernel.services.AIServiceSelector#trySelectAIService(Class, KernelArguments) + */ + public T getService(Class clazz, KernelArguments args) throws ServiceNotFoundException { + AIServiceSelection selector = serviceSelector + .trySelectAIService( + clazz, + args); + + if (selector == null) { + throw new ServiceNotFoundException("Unable to find service of type " + clazz.getName()); + } + + return selector.getService(); + } + /** * A fluent builder for creating a new instance of {@code Kernel}. */ diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java index 80ec59727..8f731915a 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java @@ -360,6 +360,16 @@ public Builder withVariable(String key, T value, value)); } + /** + * Set prompt execution settings + * + * @param executionSettings Execution settings + * @return {$code this} Builder for fluent coding + */ + public Builder withExecutionSettings(PromptExecutionSettings executionSettings) { + return withExecutionSettings(Collections.singletonList(executionSettings)); + } + /** * Set prompt execution settings * diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java index 1d12f961b..7671e9e16 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java @@ -133,13 +133,17 @@ private Flux> invokeInternalAsync( FunctionInvokingEvent updateArguments = kernelHooks .executeHooks(new FunctionInvokingEvent(this, args)); - args = updateArguments.getArguments(); + + args = KernelArguments.builder() + .withVariables(updateArguments.getArguments()) + .withExecutionSettings( + this.getExecutionSettings()) + .build(); AIServiceSelection aiServiceSelection = kernel .getServiceSelector() .trySelectAIService( TextAIService.class, - this, args); AIService client = aiServiceSelection != null ? aiServiceSelection.getService() diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java index e68e6a696..9116add44 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java @@ -20,15 +20,39 @@ public interface AIServiceSelector { * @param serviceType The type of service to select. This must be the same type with which the * service was registered in the {@link AIServiceSelection} * @param function The KernelFunction to use to select the service, or {@code null}. - * @param arguments The KernelFunctionArguments to use to select the service, or + * @param arguments The KernelArguments to use to select the service, or * {@code null}. * @param The type of service to select. * @return An {@code AIServiceSelection} containing the selected service and associated * PromptExecutionSettings. + * + * @deprecated Use {@link #trySelectAIService(Class, KernelArguments)} instead. */ + @Deprecated @Nullable AIServiceSelection trySelectAIService( Class serviceType, @Nullable KernelFunction function, @Nullable KernelArguments arguments); + + /** + * Resolves an {@link AIService} and associated and + * {@link com.microsoft.semantickernel.orchestration.PromptExecutionSettings} based on the + * associated {@link KernelFunction} and {@link KernelArguments}. + * + * @param serviceType The type of service to select. This must be the same type with which the + * service was registered in the {@link AIServiceSelection} + * @param arguments The KernelArguments to use to select the service, or + * {@code null}. + * @param The type of service to select. + * @return An {@code AIServiceSelection} containing the selected service and associated + * PromptExecutionSettings. + */ + @Nullable + default AIServiceSelection trySelectAIService( + Class serviceType, + @Nullable KernelArguments arguments) { + throw new UnsupportedOperationException( + "This method is not implemented."); + } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java index c3e42b8e6..eb7458949 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java @@ -35,6 +35,14 @@ public AIServiceSelection trySelectAIService( return trySelectAIService(serviceType, function, arguments, services); } + @Override + @Nullable + public AIServiceSelection trySelectAIService( + Class serviceType, + @Nullable KernelArguments arguments) { + return trySelectAIService(serviceType, arguments, services); + } + /** * Resolves an {@link AIService} from the {@code services} argument using the specified * {@code function} and {@code arguments} for selection. @@ -47,11 +55,36 @@ public AIServiceSelection trySelectAIService( * @param services The services to select from. * @param The type of service to select. * @return The selected service, or {@code null} if no service could be selected. + * + * @deprecated Implement {@link #trySelectAIService(Class, KernelArguments)} */ + @Deprecated @Nullable protected abstract AIServiceSelection trySelectAIService( Class serviceType, @Nullable KernelFunction function, @Nullable KernelArguments arguments, Map, AIService> services); + + + /** + * Resolves an {@link AIService} from the {@code services} argument using the specified + * {@code function} and {@code arguments} for selection. + * + * @param serviceType The type of service to select. This must be the same type with which the + * service was registered in the {@link AIServiceSelection} + * @param arguments The KernelArguments to use to select the service, or + * {@code null}. + * @param services The services to select from. + * @param The type of service to select. + * @return The selected service, or {@code null} if no service could be selected. + */ + @Nullable + protected AIServiceSelection trySelectAIService( + Class serviceType, + @Nullable KernelArguments arguments, + Map, AIService> services) { + throw new UnsupportedOperationException( + "This method is not implemented."); + } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java index 2be735439..d478a41f2 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java @@ -66,13 +66,15 @@ private static Map settingsFromFunctionSettings return null; } -// @Nullable -// @Override -// public AIServiceSelection trySelectAIService( -// Class serviceType, -// @Nullable KernelArguments arguments) { -// return selectAIService(serviceType, arguments.getPromptExecutionSettings()); -// } + @Nullable + @Override + public AIServiceSelection trySelectAIService( + Class serviceType, + @Nullable KernelArguments arguments, + Map, AIService> services) { + + return selectAIService(serviceType, arguments != null ? arguments.getExecutionSettings() : null); + } @Nullable @Override From 5859394d4bbde27e2a0d97fc09f2e9de8e34d8b4 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 24 Apr 2025 00:46:49 -0700 Subject: [PATCH 12/46] Updates to service selector --- .../services/AIServiceSelector.java | 3 --- .../services/BaseAIServiceSelector.java | 5 +--- .../services/OrderedAIServiceSelector.java | 27 +++---------------- 3 files changed, 5 insertions(+), 30 deletions(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java index 9116add44..ac95f7d35 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/AIServiceSelector.java @@ -25,10 +25,7 @@ public interface AIServiceSelector { * @param The type of service to select. * @return An {@code AIServiceSelection} containing the selected service and associated * PromptExecutionSettings. - * - * @deprecated Use {@link #trySelectAIService(Class, KernelArguments)} instead. */ - @Deprecated @Nullable AIServiceSelection trySelectAIService( Class serviceType, diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java index eb7458949..03ecdd781 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java @@ -56,9 +56,7 @@ public AIServiceSelection trySelectAIService( * @param The type of service to select. * @return The selected service, or {@code null} if no service could be selected. * - * @deprecated Implement {@link #trySelectAIService(Class, KernelArguments)} */ - @Deprecated @Nullable protected abstract AIServiceSelection trySelectAIService( Class serviceType, @@ -84,7 +82,6 @@ protected AIServiceSelection trySelectAIService( Class serviceType, @Nullable KernelArguments arguments, Map, AIService> services) { - throw new UnsupportedOperationException( - "This method is not implemented."); + return trySelectAIService(serviceType, null, arguments, services); } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java index d478a41f2..6b04fe2b4 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java @@ -57,25 +57,6 @@ private static AIServiceSelection castServiceSelection( } } - @Nullable - private static Map settingsFromFunctionSettings( - @Nullable KernelFunction function) { - if (function != null) { - return function.getExecutionSettings(); - } - return null; - } - - @Nullable - @Override - public AIServiceSelection trySelectAIService( - Class serviceType, - @Nullable KernelArguments arguments, - Map, AIService> services) { - - return selectAIService(serviceType, arguments != null ? arguments.getExecutionSettings() : null); - } - @Nullable @Override public AIServiceSelection trySelectAIService( @@ -84,11 +65,11 @@ public AIServiceSelection trySelectAIService( @Nullable KernelArguments arguments, Map, AIService> services) { - // Allow the execution settings from the kernel arguments to take precedence - Map executionSettings = settingsFromFunctionSettings( - function); + if (function == null) { + return selectAIService(serviceType, arguments != null ? arguments.getExecutionSettings() : null); + } - return selectAIService(serviceType, executionSettings); + return selectAIService(serviceType, function.getExecutionSettings()); } From 393d987f3b31093a4f86ab08738474480f3c1b64 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 24 Apr 2025 01:16:08 -0700 Subject: [PATCH 13/46] Remove unnecessary line --- .../com/microsoft/semantickernel/tests/ResponseSchemaTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/ResponseSchemaTest.java b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/ResponseSchemaTest.java index 77d4b4a36..ef792e2b2 100644 --- a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/ResponseSchemaTest.java +++ b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/ResponseSchemaTest.java @@ -160,8 +160,6 @@ private static void verifyCalled(OpenAIAsyncClient client, String expected) { writer, new JsonOptions() ); - JsonWriter format = chatCompletionsOptions.getResponseFormat() - .toJson(jsonWriter); jsonWriter.flush(); writer.flush(); From 17a920eb514ed50364b3b0bf442ffff63015f79b Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 24 Apr 2025 02:10:09 -0700 Subject: [PATCH 14/46] Fixes --- .../microsoft/semantickernel/tests/ResponseSchemaTest.java | 4 ++++ .../semantickernel/semanticfunctions/KernelArguments.java | 2 ++ .../semanticfunctions/KernelFunctionFromPrompt.java | 7 +++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/ResponseSchemaTest.java b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/ResponseSchemaTest.java index ef792e2b2..4ec677742 100644 --- a/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/ResponseSchemaTest.java +++ b/api-test/integration-tests/src/test/java/com/microsoft/semantickernel/tests/ResponseSchemaTest.java @@ -160,15 +160,19 @@ private static void verifyCalled(OpenAIAsyncClient client, String expected) { writer, new JsonOptions() ); + JsonWriter format = chatCompletionsOptions.getResponseFormat() + .toJson(jsonWriter); jsonWriter.flush(); writer.flush(); String json = String.valueOf(writer.getBuffer()) .replaceAll("\n", "") + .replaceAll("\r", "") .replaceAll(" +", ""); String expectedClean = expected .stripIndent() .replaceAll("\n", "") + .replaceAll("\r", "") .replaceAll(" +", ""); return json.equals(expectedClean); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java index 8f731915a..e4fb83192 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java @@ -409,6 +409,8 @@ public Builder withExecutionSettings(List executionS serviceId) ); } + + this.executionSettings.put(serviceId, settings); } return this; diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java index 7671e9e16..2ea909742 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java @@ -131,13 +131,12 @@ private Flux> invokeInternalAsync( LOGGER.info(SemanticKernelResources.getString("rendered.prompt"), prompt); - FunctionInvokingEvent updateArguments = kernelHooks + FunctionInvokingEvent invokingEvent = kernelHooks .executeHooks(new FunctionInvokingEvent(this, args)); args = KernelArguments.builder() - .withVariables(updateArguments.getArguments()) - .withExecutionSettings( - this.getExecutionSettings()) + .withVariables(invokingEvent.getArguments()) + .withExecutionSettings(this.getExecutionSettings()) .build(); AIServiceSelection aiServiceSelection = kernel From ed651d61d498c61ae83f19f2d9bd1537b1c358ac Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 17 Apr 2025 09:05:00 -0700 Subject: [PATCH 15/46] Add draft changes for agents --- agents/semantickernel-agents-core/pom.xml | 25 ++ .../chatcompletion/ChatCompletionAgent.java | 238 ++++++++++++++++++ .../ChatHistoryAgentThread.java | 64 +++++ agents/semantickernel-agents-openai/pom.xml | 26 ++ pom.xml | 2 + .../semantickernel-syntax-examples/pom.xml | 5 + .../samples/plugins/github/GitHubModel.java | 219 ++++++++++++++++ .../samples/plugins/github/GitHubPlugin.java | 165 ++++++++++++ .../agents/CompletionsAgent.java | 145 +++++++++++ .../semantickernel/agents/Agent.java | 60 +++++ .../agents/AgentInvokeOptions.java | 126 ++++++++++ .../agents/AgentResponseItem.java | 19 ++ .../semantickernel/agents/AgentThread.java | 45 ++++ .../agents/BaseAgentThread.java | 23 ++ .../semantickernel/agents/KernelAgent.java | 139 ++++++++++ .../services/chatcompletion/ChatHistory.java | 7 + semantickernel-bom/pom.xml | 6 + 17 files changed, 1314 insertions(+) create mode 100644 agents/semantickernel-agents-core/pom.xml create mode 100644 agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java create mode 100644 agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java create mode 100644 agents/semantickernel-agents-openai/pom.xml create mode 100644 samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java create mode 100644 samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java create mode 100644 samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/BaseAgentThread.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java diff --git a/agents/semantickernel-agents-core/pom.xml b/agents/semantickernel-agents-core/pom.xml new file mode 100644 index 000000000..4eec1b768 --- /dev/null +++ b/agents/semantickernel-agents-core/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + com.microsoft.semantic-kernel + semantickernel-parent + 1.4.4-SNAPSHOT + ../../pom.xml + + + semantickernel-agents-core + + Semantic Kernel Chat Completion Agent + Chat Completion Agent for Semantic Kernel + + + + com.microsoft.semantic-kernel + semantickernel-api + + + + \ No newline at end of file diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java new file mode 100644 index 000000000..c8c29007f --- /dev/null +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -0,0 +1,238 @@ +package com.microsoft.semantickernel.agents.chatcompletion; + +import com.microsoft.semantickernel.Kernel; +import com.microsoft.semantickernel.agents.AgentInvokeOptions; +import com.microsoft.semantickernel.agents.AgentResponseItem; +import com.microsoft.semantickernel.agents.AgentThread; +import com.microsoft.semantickernel.agents.KernelAgent; +import com.microsoft.semantickernel.builders.SemanticKernelBuilder; +import com.microsoft.semantickernel.contextvariables.ContextVariable; +import com.microsoft.semantickernel.orchestration.InvocationContext; +import com.microsoft.semantickernel.orchestration.InvocationReturnMode; +import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; +import com.microsoft.semantickernel.orchestration.ToolCallBehavior; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplateFactory; +import com.microsoft.semantickernel.services.ServiceNotFoundException; +import com.microsoft.semantickernel.services.chatcompletion.AuthorRole; +import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; +import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; +import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class ChatCompletionAgent extends KernelAgent { + + ChatCompletionAgent( + String id, + String name, + String description, + Kernel kernel, + KernelArguments kernelArguments, + InvocationContext context, + String instructions, + PromptTemplate template + ) { + super( + id, + name, + description, + kernel, + kernelArguments, + context, + instructions, + template + ); + } + + /** + * Invoke the agent with the given chat history. + * + * @param messages The chat history to process + * @param thread The agent thread to use + * @param options The options for invoking the agent + * @return A Mono containing the agent response + */ + @Override + public Mono>>> invokeAsync(List> messages, AgentThread thread, AgentInvokeOptions options) { + + Mono chatHistoryFromThread = this.ensureThreadExistsAsync(messages, thread, ChatHistoryAgentThread::new) + .cast(ChatHistoryAgentThread.class) + .map(ChatHistoryAgentThread::getChatHistory) + .flatMap(threadChatHistory -> { + return Mono.just(new ChatHistory(threadChatHistory.getMessages())); + }); + + + Mono>> updatedChatHistory = chatHistoryFromThread.flatMap( + chatHistory -> internalInvokeAsync( + this.getName(), + chatHistory, + options + ) + ); + + return updatedChatHistory.flatMap(chatMessageContents -> { + return Flux.fromIterable(chatMessageContents) + .concatMap(chatMessageContent -> this.notifyThreadOfNewMessageAsync(thread, chatMessageContent)) + .then(Mono.just(chatMessageContents)); // return the original list + }).flatMap(chatMessageContents -> { + return Mono.just(chatMessageContents.stream() + .map(chatMessageContent -> { + return new AgentResponseItem>( + chatMessageContent, + thread); + }).collect(Collectors.toList())); + }); + } + + private Mono>> internalInvokeAsync( + String agentName, + ChatHistory history, + AgentInvokeOptions options + ) { + final Kernel kernel = options.getKernel() != null ? options.getKernel() : this.kernel; + final KernelArguments arguments = mergeArguments(options.getKernelArguments()); + final String additionalInstructions = options.getAdditionalInstructions(); + final InvocationContext invocationContext = options.getInvocationContext() != null ? options.getInvocationContext() : this.invocationContext; + + try { + ChatCompletionService chatCompletionService = kernel.getService(ChatCompletionService.class, arguments); + + PromptExecutionSettings executionSettings = invocationContext.getPromptExecutionSettings() != null + ? invocationContext.getPromptExecutionSettings() + : kernelArguments.getExecutionSettings().get(chatCompletionService.getServiceId()); + + final InvocationContext newMessagesContext = InvocationContext.builder() + .withPromptExecutionSettings(executionSettings) + .withToolCallBehavior(invocationContext.getToolCallBehavior()) + .withTelemetry(invocationContext.getTelemetry()) + .withContextVariableConverter(invocationContext.getContextVariableTypes()) + .withKernelHooks(invocationContext.getKernelHooks()) + .withReturnMode(InvocationReturnMode.FULL_HISTORY) + .build(); + + return formatInstructionsAsync(kernel, arguments, newMessagesContext).flatMap( + instructions -> { + // Create a new chat history with the instructions + ChatHistory chat = new ChatHistory( + instructions + ); + + // Add agent additional instructions + if (additionalInstructions != null) { + chat.addMessage(new ChatMessageContent<>( + AuthorRole.SYSTEM, + additionalInstructions + )); + } + + chat.addAll(history); + int previousHistorySize = chat.getMessages().size(); + + return chatCompletionService.getChatMessageContentsAsync(chat, kernel, newMessagesContext) + .map(chatMessageContents -> { + return chatMessageContents.subList( + previousHistorySize, + chatMessageContents.size()); + }); + } + ); + + + } catch (ServiceNotFoundException e) { + throw new RuntimeException(e); + } + } + + /** + * Builder for creating instances of ChatCompletionAgent. + */ + public static Builder builder() { + return new Builder(); + } + + public static class Builder implements SemanticKernelBuilder { + private String id; + private String name; + private String description; + private Kernel kernel; + private KernelArguments KernelArguments; + private InvocationContext invocationContext; + private String instructions; + private PromptTemplate template; + + public Builder withId(String id) { + this.id = id; + return this; + } + + public Builder withName(String name) { + this.name = name; + return this; + } + + public Builder withDescription(String description) { + this.description = description; + return this; + } + + public Builder withKernel(Kernel kernel) { + this.kernel = kernel; + return this; + } + + public Builder withKernelArguments(KernelArguments KernelArguments) { + this.KernelArguments = KernelArguments; + return this; + } + + public Builder withInstructions(String instructions) { + this.instructions = instructions; + return this; + } + + public Builder withInvocationContext(InvocationContext invocationContext) { + this.invocationContext = invocationContext; + return this; + } + + public Builder withTemplate(PromptTemplate template) { + this.template = template; + return this; + } + + public ChatCompletionAgent build() { + return new ChatCompletionAgent( + id, + name, + description, + kernel, + KernelArguments, + invocationContext, + instructions, + template + ); + } + + public ChatCompletionAgent build(PromptTemplateConfig promptTemplateConfig, PromptTemplateFactory promptTemplateFactory) { + return new ChatCompletionAgent( + id, + name, + description, + kernel, + KernelArguments, + invocationContext, + promptTemplateConfig.getTemplate(), + promptTemplateFactory.tryCreate(promptTemplateConfig) + ); + } + } +} diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java new file mode 100644 index 000000000..b000ca9f9 --- /dev/null +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java @@ -0,0 +1,64 @@ +package com.microsoft.semantickernel.agents.chatcompletion; + +import com.microsoft.semantickernel.agents.AgentThread; +import com.microsoft.semantickernel.agents.BaseAgentThread; +import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; +import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; +import reactor.core.publisher.Mono; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.List; +import java.util.UUID; + +public class ChatHistoryAgentThread extends BaseAgentThread { + private ChatHistory chatHistory; + + public ChatHistoryAgentThread() { + } + + /** + * Constructor for com.microsoft.semantickernel.agents.chatcompletion.ChatHistoryAgentThread. + * + * @param id The ID of the thread. + * @param chatHistory The chat history. + */ + public ChatHistoryAgentThread(String id, @Nullable ChatHistory chatHistory) { + super(id); + this.chatHistory = chatHistory; + } + + /** + * Get the chat history. + * + * @return The chat history. + */ + public ChatHistory getChatHistory() { + return chatHistory; + } + + @Override + public Mono createAsync() { + if (this.id == null) { + this.id = UUID.randomUUID().toString(); + chatHistory = new ChatHistory(); + } + return Mono.just(id); + } + + @Override + public Mono deleteAsync() { + return Mono.fromRunnable(chatHistory::clear); + } + + @Override + public Mono onNewMessageAsync(ChatMessageContent newMessage) { + return Mono.fromRunnable(() -> { + chatHistory.addMessage(newMessage); + }); + } + + public List> getMessages() { + return chatHistory.getMessages(); + } +} diff --git a/agents/semantickernel-agents-openai/pom.xml b/agents/semantickernel-agents-openai/pom.xml new file mode 100644 index 000000000..815a0d5bf --- /dev/null +++ b/agents/semantickernel-agents-openai/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + com.microsoft.semantic-kernel + semantickernel-parent + 1.4.4-SNAPSHOT + + + semantickernel-agents-openai + + + 17 + 17 + UTF-8 + + + + com.microsoft.semantic-kernel + semantickernel-api + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 30963f54b..f1536e875 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,8 @@ data/semantickernel-data-azureaisearch data/semantickernel-data-jdbc data/semantickernel-data-redis + agents/semantickernel-agents-openai + agents/semantickernel-agents-core diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml b/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml index 1f6bc1811..3ccc114c1 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml @@ -49,6 +49,11 @@ semantickernel-data-redis + + com.microsoft.semantic-kernel + semantickernel-agents-core + + com.microsoft.semantic-kernel semantickernel-experimental diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java new file mode 100644 index 000000000..180ec8ed2 --- /dev/null +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java @@ -0,0 +1,219 @@ +package com.microsoft.semantickernel.samples.plugins.github; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +public abstract class GitHubModel { + public final static ObjectMapper objectMapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + @Override + public String toString() { + try { + return objectMapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + public static class User extends GitHubModel { + @JsonProperty("login") + private String login; + @JsonProperty("id") + private long id; + @JsonProperty("name") + private String name; + @JsonProperty("company") + private String company; + @JsonProperty("html_url") + private String url; + @JsonCreator + public User(@JsonProperty("login") String login, + @JsonProperty("id") long id, + @JsonProperty("name") String name, + @JsonProperty("company") String company, + @JsonProperty("html_url") String url) { + this.login = login; + this.id = id; + this.name = name; + this.company = company; + this.url = url; + } + + public String getLogin() { + return login; + } + public long getId() { + return id; + } + public String getName() { + return name; + } + public String getCompany() { + return company; + } + public String getUrl() { + return url; + } + } + + public static class Repository extends GitHubModel { + @JsonProperty("id") + private long id; + @JsonProperty("full_name") + private String name; + @JsonProperty("description") + private String description; + @JsonProperty("html_url") + private String url; + @JsonCreator + public Repository(@JsonProperty("id") long id, + @JsonProperty("full_name") String name, + @JsonProperty("description") String description, + @JsonProperty("html_url") String url) { + this.id = id; + this.name = name; + this.description = description; + this.url = url; + } + + public long getId() { + return id; + } + public String getName() { + return name; + } + public String getDescription() { + return description; + } + public String getUrl() { + return url; + } + + @Override + public String toString() { + try { + return objectMapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + } + + public static class Issue extends GitHubModel { + @JsonProperty("id") + private long id; + @JsonProperty("number") + private long number; + @JsonProperty("title") + private String title; + @JsonProperty("state") + private String state; + @JsonProperty("html_url") + private String url; + @JsonProperty("labels") + private Label[] labels; + @JsonProperty("created_at") + private String createdAt; + @JsonProperty("closed_at") + private String closedAt; + + @JsonCreator + public Issue(@JsonProperty("id") long id, + @JsonProperty("number") long number, + @JsonProperty("title") String title, + @JsonProperty("state") String state, + @JsonProperty("html_url") String url, + @JsonProperty("labels") Label[] labels, + @JsonProperty("created_at") String createdAt, + @JsonProperty("closed_at") String closedAt) { + this.id = id; + this.number = number; + this.title = title; + this.state = state; + this.url = url; + this.labels = labels; + this.createdAt = createdAt; + this.closedAt = closedAt; + } + + public long getId() { + return id; + } + public long getNumber() { + return number; + } + public String getTitle() { + return title; + } + public String getState() { + return state; + } + public String getUrl() { + return url; + } + public Label[] getLabels() { + return labels; + } + public String getCreatedAt() { + return createdAt; + } + public String getClosedAt() { + return closedAt; + } + } + + public static class IssueDetail extends Issue { + @JsonProperty("body") + private String body; + + @JsonCreator + public IssueDetail(@JsonProperty("id") long id, + @JsonProperty("number") long number, + @JsonProperty("title") String title, + @JsonProperty("state") String state, + @JsonProperty("html_url") String url, + @JsonProperty("labels") Label[] labels, + @JsonProperty("created_at") String createdAt, + @JsonProperty("closed_at") String closedAt, + @JsonProperty("body") String body) { + super(id, number, title, state, url, labels, createdAt, closedAt); + this.body = body; + } + + public String getBody() { + return body; + } + } + + public static class Label extends GitHubModel { + @JsonProperty("id") + private long id; + @JsonProperty("name") + private String name; + @JsonProperty("description") + private String description; + + @JsonCreator + public Label(@JsonProperty("id") long id, + @JsonProperty("name") String name, + @JsonProperty("description") String description) { + this.id = id; + this.name = name; + this.description = description; + } + + public long getId() { + return id; + } + public String getName() { + return name; + } + public String getDescription() { + return description; + } + } +} diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java new file mode 100644 index 000000000..2d1fb4446 --- /dev/null +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java @@ -0,0 +1,165 @@ +package com.microsoft.semantickernel.samples.plugins.github; + +import reactor.core.publisher.Mono; +import reactor.netty.http.client.HttpClient; +import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; +import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; + +import java.io.IOException; +import java.util.List; + +public class GitHubPlugin { + public static final String baseUrl = "https://api.github.com"; + private final String token; + + public GitHubPlugin(String token) { + this.token = token; + } + + @DefineKernelFunction(name = "get_user_info", description = "Get user information from GitHub", + returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$User") + public Mono getUserProfileAsync() { + HttpClient client = createClient(); + + return makeRequestAsync(client, "/user") + .map(json -> { + try { + return GitHubModel.objectMapper.readValue(json, GitHubModel.User.class); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubUser", e); + } + }); + } + + @DefineKernelFunction(name = "get_repo_info", description = "Get repository information from GitHub", + returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$Repository") + public Mono getRepositoryAsync( + @KernelFunctionParameter( + name = "organization", + description = "The name of the repository to retrieve information for" + ) String organization, + @KernelFunctionParameter( + name = "repo_name", + description = "The name of the repository to retrieve information for" + ) String repoName + ) { + HttpClient client = createClient(); + + return makeRequestAsync(client, String.format("/repos/%s/%s", organization, repoName)) + .map(json -> { + try { + return GitHubModel.objectMapper.readValue(json, GitHubModel.Repository.class); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubRepository", e); + } + }); + } + + @DefineKernelFunction(name = "get_issues", description = "Get issues from GitHub", + returnType = "java.util.List") + public Mono> getIssuesAsync( + @KernelFunctionParameter( + name = "organization", + description = "The name of the organization to retrieve issues for" + ) String organization, + @KernelFunctionParameter( + name = "repo_name", + description = "The name of the repository to retrieve issues for" + ) String repoName, + @KernelFunctionParameter( + name = "max_results", + description = "The maximum number of issues to retrieve", + required = false, + defaultValue = "10", + type = int.class + ) int maxResults, + @KernelFunctionParameter( + name = "state", + description = "The state of the issues to retrieve", + required = false, + defaultValue = "open" + ) String state, + @KernelFunctionParameter( + name = "assignee", + description = "The assignee of the issues to retrieve", + required = false + ) String assignee + ) { + HttpClient client = createClient(); + + String query = String.format("/repos/%s/%s/issues", organization, repoName); + query = buildQueryString(query, "state", state); + query = buildQueryString(query, "assignee", assignee); + query = buildQueryString(query, "per_page", String.valueOf(maxResults)); + + return makeRequestAsync(client, query) + .flatMap(json -> { + try { + GitHubModel.Issue[] issues = GitHubModel.objectMapper.readValue(json, GitHubModel.Issue[].class); + return Mono.just(List.of(issues)); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubIssues", e); + } + }); + } + + @DefineKernelFunction(name = "get_issue_detail_info", description = "Get issue detail information from GitHub", + returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$IssueDetail") + public GitHubModel.IssueDetail getIssueDetailAsync( + @KernelFunctionParameter( + name = "organization", + description = "The name of the repository to retrieve information for" + ) String organization, + @KernelFunctionParameter( + name = "repo_name", + description = "The name of the repository to retrieve information for" + ) String repoName, + @KernelFunctionParameter( + name = "issue_number", + description = "The issue number to retrieve information for", + type = int.class + ) int issueNumber + ) { + HttpClient client = createClient(); + + return makeRequestAsync(client, String.format("/repos/%s/%s/issues/%d", organization, repoName, issueNumber)) + .map(json -> { + try { + return GitHubModel.objectMapper.readValue(json, GitHubModel.IssueDetail.class); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubIssue", e); + } + }).block(); + } + + private HttpClient createClient() { + return HttpClient.create() + .baseUrl(baseUrl) + .headers(headers -> { + headers.add("User-Agent", "request"); + headers.add("Accept", "application/vnd.github+json"); + headers.add("Authorization", "Bearer " + token); + headers.add("X-GitHub-Api-Version", "2022-11-28"); + }); + } + + private static String buildQueryString(String path, String param, String value) { + if (value == null || value.isEmpty() || value.equals(KernelFunctionParameter.NO_DEFAULT_VALUE)) { + return path; + } + + return path + (path.contains("?") ? "&" : "?") + param + "=" + value; + } + + private Mono makeRequestAsync(HttpClient client, String path) { + return client + .get() + .uri(path) + .responseSingle((res, content) -> { + if (res.status().code() != 200) { + return Mono.error(new IllegalStateException("Request failed: " + res.status())); + } + return content.asString(); + }); + } +} diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java new file mode 100644 index 000000000..38e9f1e81 --- /dev/null +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java @@ -0,0 +1,145 @@ +package com.microsoft.semantickernel.samples.syntaxexamples.agents; + +import com.azure.ai.openai.OpenAIAsyncClient; +import com.azure.ai.openai.OpenAIClientBuilder; +import com.azure.core.credential.AzureKeyCredential; +import com.azure.core.credential.KeyCredential; +import com.microsoft.semantickernel.Kernel; +import com.microsoft.semantickernel.agents.AgentInvokeOptions; +import com.microsoft.semantickernel.agents.chatcompletion.ChatCompletionAgent; +import com.microsoft.semantickernel.agents.chatcompletion.ChatHistoryAgentThread; +import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; +import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter; +import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; +import com.microsoft.semantickernel.implementation.templateengine.tokenizer.DefaultPromptTemplate; +import com.microsoft.semantickernel.orchestration.InvocationContext; +import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; +import com.microsoft.semantickernel.orchestration.ToolCallBehavior; +import com.microsoft.semantickernel.plugin.KernelPluginFactory; +import com.microsoft.semantickernel.samples.plugins.github.GitHubModel; +import com.microsoft.semantickernel.samples.plugins.github.GitHubPlugin; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; +import com.microsoft.semantickernel.services.chatcompletion.AuthorRole; +import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; +import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; + +import java.util.List; +import java.util.Scanner; + +public class CompletionsAgent { + private static final String CLIENT_KEY = System.getenv("CLIENT_KEY"); + private static final String AZURE_CLIENT_KEY = System.getenv("AZURE_CLIENT_KEY"); + + // Only required if AZURE_CLIENT_KEY is set + private static final String CLIENT_ENDPOINT = System.getenv("CLIENT_ENDPOINT"); + private static final String MODEL_ID = System.getenv() + .getOrDefault("MODEL_ID", "gpt-35-turbo"); + + private static final String GITHUB_PAT = System.getenv("GITHUB_PAT"); + public static void main(String[] args) { + System.out.println("======== ChatCompletion Agent ========"); + + OpenAIAsyncClient client; + + if (AZURE_CLIENT_KEY != null) { + client = new OpenAIClientBuilder() + .credential(new AzureKeyCredential(AZURE_CLIENT_KEY)) + .endpoint(CLIENT_ENDPOINT) + .buildAsyncClient(); + + } else { + client = new OpenAIClientBuilder() + .credential(new KeyCredential(CLIENT_KEY)) + .buildAsyncClient(); + } + + ChatCompletionService chatCompletion = OpenAIChatCompletion.builder() + .withModelId(MODEL_ID) + .withOpenAIAsyncClient(client) + .build(); + + System.out.println("------------------------"); + + ContextVariableTypes.addGlobalConverter( + new ContextVariableTypeConverter<>( + GitHubModel.Issue.class, + o -> (GitHubModel.Issue) o, + o -> o.toString(), + s -> null + ) + ); + + Kernel kernel = Kernel.builder() + .withAIService(ChatCompletionService.class, chatCompletion) + .withPlugin(KernelPluginFactory.createFromObject(new GitHubPlugin(GITHUB_PAT), + "GitHubPlugin")) + .build(); + + InvocationContext invocationContext = InvocationContext.builder() + .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) + .build(); + + ChatCompletionAgent agent = ChatCompletionAgent.builder() + .withKernel(kernel) + .withKernelArguments( + KernelArguments.builder() + .withVariable("repository", "microsoft/semantic-kernel-java") + .withExecutionSettings(PromptExecutionSettings.builder() + .build()) + .build() + ) + .withInvocationContext(invocationContext) + .withTemplate( + DefaultPromptTemplate.build( + PromptTemplateConfig.builder() + .withTemplate( + """ + You are an agent designed to query and retrieve information from a single GitHub repository in a read-only manner. + You are also able to access the profile of the active user. + + Use the current date and time to provide up-to-date details or time-sensitive responses. + + The repository you are querying is a public repository with the following name: {{$repository}} + + The current date and time is: {{$now}}. + """ + ) + .build() + ) + ).build(); + + ChatHistoryAgentThread agentThread = new ChatHistoryAgentThread(); + agentThread.createAsync().block(); + + Scanner scanner = new Scanner(System.in); + + while (true) { + System.out.print("> "); + + String input = scanner.nextLine(); + if (input.equalsIgnoreCase("exit")) { + break; + } + + var message = new ChatMessageContent<>(AuthorRole.USER, input); + KernelArguments arguments = KernelArguments.builder() + .withVariable("now", System.currentTimeMillis()) + .build(); + + var responses = agent.invokeAsync( + List.of(message), + agentThread, + AgentInvokeOptions.builder() + .withKernel(kernel) + .withKernelArguments(arguments) + .build() + ).block(); + + for (var response : responses) { + System.out.println("> " + response.getMessage()); + } + } + } + +} diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java new file mode 100644 index 000000000..314201e9a --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java @@ -0,0 +1,60 @@ +package com.microsoft.semantickernel.agents; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; +import java.util.function.Supplier; + +import com.microsoft.semantickernel.Kernel; +import com.microsoft.semantickernel.orchestration.InvocationContext; +import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; +import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; +import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +/** + * Interface for a semantic kernel agent. + */ +public interface Agent { + + /** + * Gets the agent's ID. + * + * @return The agent's ID + */ + String getId(); + + /** + * Gets the agent's name. + * + * @return The agent's name + */ + String getName(); + + /** + * Gets the agent's description. + * + * @return The agent's description + */ + String getDescription(); + + /** + * Invoke the agent with the given chat history. + * + * @param messages The chat history to process + * @param thread The agent thread to use + * @param options The options for invoking the agent + * @return A Mono containing the agent response + */ + Mono>>> invokeAsync(List> messages, AgentThread thread, AgentInvokeOptions options); + + + + + Mono notifyThreadOfNewMessageAsync(AgentThread thread, ChatMessageContent newMessage); +} \ No newline at end of file diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java new file mode 100644 index 000000000..a542c40a5 --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java @@ -0,0 +1,126 @@ +package com.microsoft.semantickernel.agents; + +import com.microsoft.semantickernel.Kernel; +import com.microsoft.semantickernel.builders.SemanticKernelBuilder; +import com.microsoft.semantickernel.orchestration.InvocationContext; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; + +/** + * Options for invoking an agent. + */ +public class AgentInvokeOptions { + + private final KernelArguments KernelArguments; + private final Kernel kernel; + private final String additionalInstructions; + private final InvocationContext invocationContext; + + + /** + * Constructor for AgentInvokeOptions. + * + * @param KernelArguments The arguments for the kernel function. + * @param kernel The kernel to use. + * @param additionalInstructions Additional instructions for the agent. + * @param invocationContext The invocation context. + */ + public AgentInvokeOptions(KernelArguments KernelArguments, Kernel kernel, String additionalInstructions, + InvocationContext invocationContext) { + this.KernelArguments = KernelArguments; + this.kernel = kernel; + this.additionalInstructions = additionalInstructions; + this.invocationContext = invocationContext; + } + + public KernelArguments getKernelArguments() { + return KernelArguments; + } + + public Kernel getKernel() { + return kernel; + } + + public String getAdditionalInstructions() { + return additionalInstructions; + } + + public InvocationContext getInvocationContext() { + return invocationContext; + } + + + + /** + * Builder for AgentInvokeOptions. + */ + public static Builder builder() { + return new Builder(); + } + + public static class Builder implements SemanticKernelBuilder { + + private KernelArguments kernelArguments; + private Kernel kernel; + private String additionalInstructions; + private InvocationContext invocationContext; + + /** + * Set the kernel arguments. + * + * @param kernelArguments The kernel arguments. + * @return The builder. + */ + public Builder withKernelArguments(KernelArguments kernelArguments) { + this.kernelArguments = kernelArguments; + return this; + } + + /** + * Set the kernel. + * + * @param kernel The kernel. + * @return The builder. + */ + public Builder withKernel(Kernel kernel) { + this.kernel = kernel; + return this; + } + + /** + * Set additional instructions. + * + * @param additionalInstructions The additional instructions. + * @return The builder. + */ + public Builder withAdditionalInstructions(String additionalInstructions) { + this.additionalInstructions = additionalInstructions; + return this; + } + + /** + * Set the invocation context. + * + * @param invocationContext The invocation context. + * @return The builder. + */ + public Builder withInvocationContext(InvocationContext invocationContext) { + this.invocationContext = invocationContext; + return this; + } + + /** + * Build the object. + * + * @return a constructed object. + */ + @Override + public AgentInvokeOptions build() { + return new AgentInvokeOptions( + kernelArguments != null ? kernelArguments : com.microsoft.semantickernel.semanticfunctions.KernelArguments.builder().build(), + kernel != null ? kernel : Kernel.builder().build(), + additionalInstructions, + invocationContext + ); + } + } +} \ No newline at end of file diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java new file mode 100644 index 000000000..61ffdd6d0 --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java @@ -0,0 +1,19 @@ +package com.microsoft.semantickernel.agents; + +public class AgentResponseItem { + private final T message; + private final AgentThread thread; + + public AgentResponseItem(T message, AgentThread thread) { + this.message = message; + this.thread = thread; + } + + public T getMessage() { + return message; + } + + public AgentThread getThread() { + return thread; + } +} diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java new file mode 100644 index 000000000..0c83751a9 --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java @@ -0,0 +1,45 @@ +package com.microsoft.semantickernel.agents; + +import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; +import reactor.core.publisher.Mono; + +/** + * Interface for an agent thread. + */ +public interface AgentThread { + /** + * Get the thread ID. + * + * @return The thread ID. + */ + String getId(); + + /** + * Create a new thread. + * + * @return A Mono containing the thread ID. + */ + Mono createAsync(); + + /** + * Delete the thread. + * + * @return A Mono indicating completion. + */ + Mono deleteAsync(); + + /** + * Check if the thread is deleted. + * + * @return A Mono containing true if the thread is deleted, false otherwise. + */ + boolean isDeleted(); + + /** + * Handle a new message in the thread. + * + * @param newMessage The new message to handle. + * @return A Mono indicating completion. + */ + Mono onNewMessageAsync(ChatMessageContent newMessage); +} \ No newline at end of file diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/BaseAgentThread.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/BaseAgentThread.java new file mode 100644 index 000000000..b7c97eea9 --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/BaseAgentThread.java @@ -0,0 +1,23 @@ +package com.microsoft.semantickernel.agents; + +public abstract class BaseAgentThread implements AgentThread { + + protected String id; + protected boolean isDeleted; + + public BaseAgentThread() { + } + + public BaseAgentThread(String id) { + this.id = id; + } + + @Override + public String getId() { + return id; + } + @Override + public boolean isDeleted() { + return isDeleted; + } +} diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java new file mode 100644 index 000000000..8aaa432ef --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java @@ -0,0 +1,139 @@ +package com.microsoft.semantickernel.agents; + +import com.microsoft.semantickernel.Kernel; +import com.microsoft.semantickernel.orchestration.InvocationContext; +import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; +import com.microsoft.semantickernel.semanticfunctions.KernelArguments; +import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; +import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Supplier; + +public abstract class KernelAgent implements Agent { + + protected final String id; + + protected final String name; + + protected final String description; + + protected final Kernel kernel; + protected final KernelArguments kernelArguments; + protected final InvocationContext invocationContext; + protected final String instructions; + + protected final PromptTemplate template; + + protected KernelAgent( + String id, + String name, + String description, + Kernel kernel, + KernelArguments kernelArguments, + InvocationContext invocationContext, + String instructions, + PromptTemplate template + ) { + this.id = id != null ? id : UUID.randomUUID().toString(); + this.name = name; + this.description = description; + this.kernel = kernel; + this.kernelArguments = kernelArguments; + this.invocationContext = invocationContext; + this.instructions = instructions; + this.template = template; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public Kernel getKernel() { + return kernel; + } + + public KernelArguments getKernelArguments() { + return kernelArguments; + } + + public String getInstructions() { + return instructions; + } + + public PromptTemplate getTemplate() { + return template; + } + + protected Mono ensureThreadExistsAsync(List> messages, AgentThread thread, Supplier constructor) { + return Mono.defer(() -> { + T newThread = thread != null ? (T) thread : constructor.get(); + + return newThread.createAsync() + .thenMany(Flux.fromIterable(messages)) + .concatMap(message -> { + return notifyThreadOfNewMessageAsync(newThread, message) + .then(Mono.just(message)); + }) + .then(Mono.just(newThread)); + }); + } + + @Override + public Mono notifyThreadOfNewMessageAsync(AgentThread thread, ChatMessageContent message) { + return Mono.defer(() -> { + return thread.onNewMessageAsync(message); + }); + } + + + /** + * Merges the provided arguments with the current arguments. + * Provided arguments will override the current arguments. + * + * @param arguments The arguments to merge with the current arguments. + */ + protected KernelArguments mergeArguments(KernelArguments arguments) { + if (arguments == null) { + return kernelArguments; + } + + Map executionSettings = new HashMap<>(kernelArguments.getExecutionSettings()); + executionSettings.putAll(arguments.getExecutionSettings()); + + return KernelArguments.builder() + .withVariables(kernelArguments) + .withVariables(arguments) + .withExecutionSettings(executionSettings) + .build(); + } + + /** + * Formats the instructions using the provided kernel, arguments, and context. + * + * @param kernel The kernel to use for formatting. + * @param arguments The arguments to use for formatting. + * @param context The context to use for formatting. + * @return A Mono that resolves to the formatted instructions. + */ + protected Mono formatInstructionsAsync(Kernel kernel, KernelArguments arguments, InvocationContext context) { + if (template != null) { + return template.renderAsync(kernel, arguments, context); + } else { + return Mono.just(instructions); + } + } +} diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatHistory.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatHistory.java index 25cd8ea89..df5f18322 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatHistory.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatHistory.java @@ -187,6 +187,13 @@ public ChatHistory addSystemMessage(String content) { return addMessage(AuthorRole.SYSTEM, content); } + /** + * Clear the chat history + */ + public void clear() { + chatMessageContents.clear(); + } + /** * Add all messages to the chat history * @param messages The messages to add to the chat history diff --git a/semantickernel-bom/pom.xml b/semantickernel-bom/pom.xml index bb4d766fd..32ca102b1 100644 --- a/semantickernel-bom/pom.xml +++ b/semantickernel-bom/pom.xml @@ -112,6 +112,12 @@ ${project.version} + + com.microsoft.semantic-kernel + semantickernel-agents-core + ${project.version} + + com.azure azure-ai-openai From e242d99f517383055184609488dedf4c3cbb9c1b Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 21 Apr 2025 11:00:31 -0700 Subject: [PATCH 16/46] Updates --- .../agents/chatcompletion/ChatCompletionAgent.java | 6 +++--- .../samples/plugins/github/GitHubPlugin.java | 2 +- .../syntaxexamples/agents/CompletionsAgent.java | 11 ++++------- .../com/microsoft/semantickernel/agents/Agent.java | 8 +++++--- .../microsoft/semantickernel/agents/KernelAgent.java | 8 +++----- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index c8c29007f..413abbc2b 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -110,7 +110,7 @@ private Mono>> internalInvokeAsync( ? invocationContext.getPromptExecutionSettings() : kernelArguments.getExecutionSettings().get(chatCompletionService.getServiceId()); - final InvocationContext newMessagesContext = InvocationContext.builder() + final InvocationContext updatedInvocationContext = InvocationContext.builder() .withPromptExecutionSettings(executionSettings) .withToolCallBehavior(invocationContext.getToolCallBehavior()) .withTelemetry(invocationContext.getTelemetry()) @@ -119,7 +119,7 @@ private Mono>> internalInvokeAsync( .withReturnMode(InvocationReturnMode.FULL_HISTORY) .build(); - return formatInstructionsAsync(kernel, arguments, newMessagesContext).flatMap( + return formatInstructionsAsync(kernel, arguments, updatedInvocationContext).flatMap( instructions -> { // Create a new chat history with the instructions ChatHistory chat = new ChatHistory( @@ -137,7 +137,7 @@ private Mono>> internalInvokeAsync( chat.addAll(history); int previousHistorySize = chat.getMessages().size(); - return chatCompletionService.getChatMessageContentsAsync(chat, kernel, newMessagesContext) + return chatCompletionService.getChatMessageContentsAsync(chat, kernel, updatedInvocationContext) .map(chatMessageContents -> { return chatMessageContents.subList( previousHistorySize, diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java index 2d1fb4446..d3c59a152 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java @@ -103,7 +103,7 @@ public Mono> getIssuesAsync( }); } - @DefineKernelFunction(name = "get_issue_detail_info", description = "Get issue detail information from GitHub", + @DefineKernelFunction(name = "get_issue_detail_info", description = "Get detail information of a single issue from GitHub", returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$IssueDetail") public GitHubModel.IssueDetail getIssueDetailAsync( @KernelFunctionParameter( diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java index 38e9f1e81..9e2d82c70 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java @@ -34,7 +34,7 @@ public class CompletionsAgent { // Only required if AZURE_CLIENT_KEY is set private static final String CLIENT_ENDPOINT = System.getenv("CLIENT_ENDPOINT"); private static final String MODEL_ID = System.getenv() - .getOrDefault("MODEL_ID", "gpt-35-turbo"); + .getOrDefault("MODEL_ID", "gpt-4o"); private static final String GITHUB_PAT = System.getenv("GITHUB_PAT"); public static void main(String[] args) { @@ -77,7 +77,7 @@ public static void main(String[] args) { .build(); InvocationContext invocationContext = InvocationContext.builder() - .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) + .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(false)) .build(); ChatCompletionAgent agent = ChatCompletionAgent.builder() @@ -127,7 +127,7 @@ public static void main(String[] args) { .withVariable("now", System.currentTimeMillis()) .build(); - var responses = agent.invokeAsync( + var response = agent.invokeAsync( List.of(message), agentThread, AgentInvokeOptions.builder() @@ -136,10 +136,7 @@ public static void main(String[] args) { .build() ).block(); - for (var response : responses) { - System.out.println("> " + response.getMessage()); - } + System.out.println("> " + response.get(response.size() - 1).getMessage()); } } - } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java index 314201e9a..3a82550c6 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java @@ -53,8 +53,10 @@ public interface Agent { */ Mono>>> invokeAsync(List> messages, AgentThread thread, AgentInvokeOptions options); - - - + /** + * Notifies the agent of a new message. + * + * @param thread The agent thread to use + */ Mono notifyThreadOfNewMessageAsync(AgentThread thread, ChatMessageContent newMessage); } \ No newline at end of file diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java index 8aaa432ef..a9af6f87e 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java @@ -2,6 +2,7 @@ import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.orchestration.InvocationContext; +import com.microsoft.semantickernel.orchestration.InvocationReturnMode; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; @@ -18,16 +19,12 @@ public abstract class KernelAgent implements Agent { protected final String id; - protected final String name; - protected final String description; - protected final Kernel kernel; protected final KernelArguments kernelArguments; protected final InvocationContext invocationContext; protected final String instructions; - protected final PromptTemplate template; protected KernelAgent( @@ -45,7 +42,8 @@ protected KernelAgent( this.description = description; this.kernel = kernel; this.kernelArguments = kernelArguments; - this.invocationContext = invocationContext; + this.invocationContext = invocationContext != null + ? invocationContext : InvocationContext.builder().withReturnMode(InvocationReturnMode.FULL_HISTORY).build(); this.instructions = instructions; this.template = template; } From 83daec2a7de3a75b1f06f2f59489daab2dd56054 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 21 Apr 2025 22:30:01 -0700 Subject: [PATCH 17/46] Renaming sample and adjust invocation context --- .../chatcompletion/ChatCompletionAgent.java | 32 ++++++++++++------- ...letionsAgent.java => CompletionAgent.java} | 4 +-- 2 files changed, 23 insertions(+), 13 deletions(-) rename samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/{CompletionsAgent.java => CompletionAgent.java} (99%) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index 413abbc2b..b521ce59d 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -106,20 +106,30 @@ private Mono>> internalInvokeAsync( try { ChatCompletionService chatCompletionService = kernel.getService(ChatCompletionService.class, arguments); - PromptExecutionSettings executionSettings = invocationContext.getPromptExecutionSettings() != null + PromptExecutionSettings executionSettings = invocationContext != null && invocationContext.getPromptExecutionSettings() != null ? invocationContext.getPromptExecutionSettings() : kernelArguments.getExecutionSettings().get(chatCompletionService.getServiceId()); - final InvocationContext updatedInvocationContext = InvocationContext.builder() + ToolCallBehavior toolCallBehavior = invocationContext != null + ? invocationContext.getToolCallBehavior() + : ToolCallBehavior.allowAllKernelFunctions(false); + + // Build base invocation context + InvocationContext.Builder builder = InvocationContext.builder() .withPromptExecutionSettings(executionSettings) - .withToolCallBehavior(invocationContext.getToolCallBehavior()) - .withTelemetry(invocationContext.getTelemetry()) - .withContextVariableConverter(invocationContext.getContextVariableTypes()) - .withKernelHooks(invocationContext.getKernelHooks()) - .withReturnMode(InvocationReturnMode.FULL_HISTORY) - .build(); - - return formatInstructionsAsync(kernel, arguments, updatedInvocationContext).flatMap( + .withToolCallBehavior(toolCallBehavior) + .withReturnMode(InvocationReturnMode.FULL_HISTORY); + + if (invocationContext != null) { + builder = builder + .withTelemetry(invocationContext.getTelemetry()) + .withContextVariableConverter(invocationContext.getContextVariableTypes()) + .withKernelHooks(invocationContext.getKernelHooks()); + } + + InvocationContext agentInvocationContext = builder.build(); + + return formatInstructionsAsync(kernel, arguments, agentInvocationContext).flatMap( instructions -> { // Create a new chat history with the instructions ChatHistory chat = new ChatHistory( @@ -137,7 +147,7 @@ private Mono>> internalInvokeAsync( chat.addAll(history); int previousHistorySize = chat.getMessages().size(); - return chatCompletionService.getChatMessageContentsAsync(chat, kernel, updatedInvocationContext) + return chatCompletionService.getChatMessageContentsAsync(chat, kernel, agentInvocationContext) .map(chatMessageContents -> { return chatMessageContents.subList( previousHistorySize, diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java similarity index 99% rename from samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java rename to samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java index 9e2d82c70..180b0c804 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionsAgent.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java @@ -27,7 +27,7 @@ import java.util.List; import java.util.Scanner; -public class CompletionsAgent { +public class CompletionAgent { private static final String CLIENT_KEY = System.getenv("CLIENT_KEY"); private static final String AZURE_CLIENT_KEY = System.getenv("AZURE_CLIENT_KEY"); @@ -77,7 +77,7 @@ public static void main(String[] args) { .build(); InvocationContext invocationContext = InvocationContext.builder() - .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(false)) + .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) .build(); ChatCompletionAgent agent = ChatCompletionAgent.builder() From 4664b2b835cf364b305c880ca4fe0ab752142b2c Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 24 Apr 2025 22:35:58 -0700 Subject: [PATCH 18/46] Updates --- .../chatcompletion/ChatCompletionAgent.java | 160 ++++++++++++------ .../ChatHistoryAgentThread.java | 51 +++++- .../agents/CompletionAgent.java | 26 ++- .../agents/AgentInvokeOptions.java | 20 ++- .../semantickernel/agents/AgentThread.java | 7 + .../semantickernel/agents/KernelAgent.java | 74 +++++--- .../chatcompletion/ChatMessageContent.java | 44 +++++ 7 files changed, 289 insertions(+), 93 deletions(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index b521ce59d..2e9a0d7df 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -6,7 +6,6 @@ import com.microsoft.semantickernel.agents.AgentThread; import com.microsoft.semantickernel.agents.KernelAgent; import com.microsoft.semantickernel.builders.SemanticKernelBuilder; -import com.microsoft.semantickernel.contextvariables.ContextVariable; import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.orchestration.InvocationReturnMode; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; @@ -23,14 +22,13 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import javax.annotation.Nullable; import java.util.List; -import java.util.Map; -import java.util.function.Function; import java.util.stream.Collectors; public class ChatCompletionAgent extends KernelAgent { - ChatCompletionAgent( + private ChatCompletionAgent( String id, String name, String description, @@ -61,43 +59,49 @@ public class ChatCompletionAgent extends KernelAgent { * @return A Mono containing the agent response */ @Override - public Mono>>> invokeAsync(List> messages, AgentThread thread, AgentInvokeOptions options) { - - Mono chatHistoryFromThread = this.ensureThreadExistsAsync(messages, thread, ChatHistoryAgentThread::new) - .cast(ChatHistoryAgentThread.class) - .map(ChatHistoryAgentThread::getChatHistory) - .flatMap(threadChatHistory -> { - return Mono.just(new ChatHistory(threadChatHistory.getMessages())); - }); - - - Mono>> updatedChatHistory = chatHistoryFromThread.flatMap( - chatHistory -> internalInvokeAsync( - this.getName(), - chatHistory, - options - ) - ); + public Mono>>> invokeAsync( + List> messages, + AgentThread thread, + @Nullable AgentInvokeOptions options + ) { + return ensureThreadExistsWithMessagesAsync(messages, thread, ChatHistoryAgentThread::new) + .cast(ChatHistoryAgentThread.class) + .flatMap(agentThread -> { + // Extract the chat history from the thread + ChatHistory history = new ChatHistory( + agentThread.getChatHistory().getMessages() + ); - return updatedChatHistory.flatMap(chatMessageContents -> { - return Flux.fromIterable(chatMessageContents) - .concatMap(chatMessageContent -> this.notifyThreadOfNewMessageAsync(thread, chatMessageContent)) - .then(Mono.just(chatMessageContents)); // return the original list - }).flatMap(chatMessageContents -> { - return Mono.just(chatMessageContents.stream() - .map(chatMessageContent -> { - return new AgentResponseItem>( - chatMessageContent, - thread); - }).collect(Collectors.toList())); - }); + // Invoke the agent with the chat history + return internalInvokeAsync( + history, + options + ) + .flatMapMany(Flux::fromIterable) + // notify on the new thread instance + .concatMap(agentMessage -> { + // Set the author name for the message + agentMessage.setAuthorName(this.name); + + return this.notifyThreadOfNewMessageAsync(agentThread, agentMessage).thenReturn(agentMessage); + }) + .collectList() + .map(chatMessageContents -> + chatMessageContents.stream() + .map(message -> new AgentResponseItem>(message, agentThread)) + .collect(Collectors.toList()) + ); + }); } private Mono>> internalInvokeAsync( - String agentName, ChatHistory history, - AgentInvokeOptions options + @Nullable AgentInvokeOptions options ) { + if (options == null) { + options = new AgentInvokeOptions(); + } + final Kernel kernel = options.getKernel() != null ? options.getKernel() : this.kernel; final KernelArguments arguments = mergeArguments(options.getKernelArguments()); final String additionalInstructions = options.getAdditionalInstructions(); @@ -112,13 +116,13 @@ private Mono>> internalInvokeAsync( ToolCallBehavior toolCallBehavior = invocationContext != null ? invocationContext.getToolCallBehavior() - : ToolCallBehavior.allowAllKernelFunctions(false); + : ToolCallBehavior.allowAllKernelFunctions(true); // Build base invocation context InvocationContext.Builder builder = InvocationContext.builder() .withPromptExecutionSettings(executionSettings) .withToolCallBehavior(toolCallBehavior) - .withReturnMode(InvocationReturnMode.FULL_HISTORY); + .withReturnMode(InvocationReturnMode.NEW_MESSAGES_ONLY); if (invocationContext != null) { builder = builder @@ -129,7 +133,7 @@ private Mono>> internalInvokeAsync( InvocationContext agentInvocationContext = builder.build(); - return formatInstructionsAsync(kernel, arguments, agentInvocationContext).flatMap( + return renderInstructionsAsync(kernel, arguments, agentInvocationContext).flatMap( instructions -> { // Create a new chat history with the instructions ChatHistory chat = new ChatHistory( @@ -144,24 +148,26 @@ private Mono>> internalInvokeAsync( )); } + // Add the chat history to the new chat chat.addAll(history); - int previousHistorySize = chat.getMessages().size(); - - return chatCompletionService.getChatMessageContentsAsync(chat, kernel, agentInvocationContext) - .map(chatMessageContents -> { - return chatMessageContents.subList( - previousHistorySize, - chatMessageContents.size()); - }); + + return chatCompletionService.getChatMessageContentsAsync(chat, kernel, agentInvocationContext); } ); - } catch (ServiceNotFoundException e) { throw new RuntimeException(e); } } + + @Override + public Mono notifyThreadOfNewMessageAsync(AgentThread thread, ChatMessageContent message) { + return Mono.defer(() -> { + return thread.onNewMessageAsync(message); + }); + } + /** * Builder for creating instances of ChatCompletionAgent. */ @@ -174,71 +180,123 @@ public static class Builder implements SemanticKernelBuilder deleteAsync() { return Mono.fromRunnable(chatHistory::clear); } + /** + * Create a copy of the thread. + * + * @return A new instance of the thread. + */ + @Override + public ChatHistoryAgentThread copy() { + return new ChatHistoryAgentThread(this.id, new ChatHistory(chatHistory.getMessages())); + } + @Override public Mono onNewMessageAsync(ChatMessageContent newMessage) { return Mono.fromRunnable(() -> { @@ -61,4 +73,41 @@ public Mono onNewMessageAsync(ChatMessageContent newMessage) { public List> getMessages() { return chatHistory.getMessages(); } + + + public static Builder builder() { + return new Builder(); + } + + public static class Builder implements SemanticKernelBuilder { + private String id; + private ChatHistory chatHistory; + + /** + * Set the ID of the thread. + * + * @param id The ID of the thread. + * @return The builder instance. + */ + public Builder withId(String id) { + this.id = id; + return this; + } + + /** + * Set the chat history. + * + * @param chatHistory The chat history. + * @return The builder instance. + */ + public Builder withChatHistory(ChatHistory chatHistory) { + this.chatHistory = chatHistory; + return this; + } + + @Override + public ChatHistoryAgentThread build() { + return new ChatHistoryAgentThread(id, chatHistory); + } + } } diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java index 180b0c804..1e5a665a9 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java @@ -54,22 +54,13 @@ public static void main(String[] args) { .buildAsyncClient(); } + System.out.println("------------------------"); + ChatCompletionService chatCompletion = OpenAIChatCompletion.builder() .withModelId(MODEL_ID) .withOpenAIAsyncClient(client) .build(); - System.out.println("------------------------"); - - ContextVariableTypes.addGlobalConverter( - new ContextVariableTypeConverter<>( - GitHubModel.Issue.class, - o -> (GitHubModel.Issue) o, - o -> o.toString(), - s -> null - ) - ); - Kernel kernel = Kernel.builder() .withAIService(ChatCompletionService.class, chatCompletion) .withPlugin(KernelPluginFactory.createFromObject(new GitHubPlugin(GITHUB_PAT), @@ -78,6 +69,12 @@ public static void main(String[] args) { InvocationContext invocationContext = InvocationContext.builder() .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) + .withContextVariableConverter(new ContextVariableTypeConverter<>( + GitHubModel.Issue.class, + o -> (GitHubModel.Issue) o, + o -> o.toString(), + s -> null + )) .build(); ChatCompletionAgent agent = ChatCompletionAgent.builder() @@ -110,8 +107,6 @@ public static void main(String[] args) { ).build(); ChatHistoryAgentThread agentThread = new ChatHistoryAgentThread(); - agentThread.createAsync().block(); - Scanner scanner = new Scanner(System.in); while (true) { @@ -136,7 +131,10 @@ public static void main(String[] args) { .build() ).block(); - System.out.println("> " + response.get(response.size() - 1).getMessage()); + var lastResponse = response.get(response.size() - 1); + + System.out.println("> " + lastResponse.getMessage()); + agentThread = (ChatHistoryAgentThread) lastResponse.getThread(); } } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java index a542c40a5..d5a99b5ae 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java @@ -5,6 +5,8 @@ import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.semanticfunctions.KernelArguments; +import javax.annotation.Nullable; + /** * Options for invoking an agent. */ @@ -15,6 +17,12 @@ public class AgentInvokeOptions { private final String additionalInstructions; private final InvocationContext invocationContext; + /** + * Default constructor for AgentInvokeOptions. + */ + public AgentInvokeOptions() { + this(null, null, null, null); + } /** * Constructor for AgentInvokeOptions. @@ -24,8 +32,10 @@ public class AgentInvokeOptions { * @param additionalInstructions Additional instructions for the agent. * @param invocationContext The invocation context. */ - public AgentInvokeOptions(KernelArguments KernelArguments, Kernel kernel, String additionalInstructions, - InvocationContext invocationContext) { + public AgentInvokeOptions(@Nullable KernelArguments KernelArguments, + @Nullable Kernel kernel, + @Nullable String additionalInstructions, + @Nullable InvocationContext invocationContext) { this.KernelArguments = KernelArguments; this.kernel = kernel; this.additionalInstructions = additionalInstructions; @@ -116,10 +126,10 @@ public Builder withInvocationContext(InvocationContext invocationContext) { @Override public AgentInvokeOptions build() { return new AgentInvokeOptions( - kernelArguments != null ? kernelArguments : com.microsoft.semantickernel.semanticfunctions.KernelArguments.builder().build(), - kernel != null ? kernel : Kernel.builder().build(), + kernelArguments, + kernel, additionalInstructions, - invocationContext + invocationContext ); } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java index 0c83751a9..d369d999d 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java @@ -35,6 +35,13 @@ public interface AgentThread { */ boolean isDeleted(); + /** + * Create a copy of the thread. + * + * @return A new instance of the thread. + */ + AgentThread copy(); + /** * Handle a new message in the thread. * diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java index a9af6f87e..e5f54a6d6 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java @@ -48,55 +48,69 @@ protected KernelAgent( this.template = template; } + /** + * Gets the agent's ID. + * + * @return The agent's ID + */ public String getId() { return id; } + /** + * Gets the agent's name. + * + * @return The agent's name + */ public String getName() { return name; } + /** + * Gets the agent's description. + * + * @return The agent's description + */ public String getDescription() { return description; } + /** + * Gets the kernel used by the agent. + * + * @return The kernel used by the agent + */ public Kernel getKernel() { return kernel; } + /** + * Gets the invocation context used by the agent. + * + * @return The invocation context used by the agent + */ public KernelArguments getKernelArguments() { return kernelArguments; } + /** + * Gets the invocation context used by the agent. + * + * @return The invocation context used by the agent + */ public String getInstructions() { return instructions; } + /** + * Gets the invocation context used by the agent. + * + * @return The invocation context used by the agent + */ public PromptTemplate getTemplate() { return template; } - protected Mono ensureThreadExistsAsync(List> messages, AgentThread thread, Supplier constructor) { - return Mono.defer(() -> { - T newThread = thread != null ? (T) thread : constructor.get(); - - return newThread.createAsync() - .thenMany(Flux.fromIterable(messages)) - .concatMap(message -> { - return notifyThreadOfNewMessageAsync(newThread, message) - .then(Mono.just(message)); - }) - .then(Mono.just(newThread)); - }); - } - - @Override - public Mono notifyThreadOfNewMessageAsync(AgentThread thread, ChatMessageContent message) { - return Mono.defer(() -> { - return thread.onNewMessageAsync(message); - }); - } - /** * Merges the provided arguments with the current arguments. @@ -127,11 +141,27 @@ protected KernelArguments mergeArguments(KernelArguments arguments) { * @param context The context to use for formatting. * @return A Mono that resolves to the formatted instructions. */ - protected Mono formatInstructionsAsync(Kernel kernel, KernelArguments arguments, InvocationContext context) { + protected Mono renderInstructionsAsync(Kernel kernel, KernelArguments arguments, InvocationContext context) { if (template != null) { return template.renderAsync(kernel, arguments, context); } else { return Mono.just(instructions); } } + + protected Mono ensureThreadExistsWithMessagesAsync(List> messages, AgentThread thread, Supplier threadSupplier) { + return Mono.defer(() -> { + // Check if the thread already exists + // If it does, we can work with a copy of it + AgentThread newThread = thread == null ? threadSupplier.get() : thread.copy(); + + return newThread.createAsync() + .thenMany(Flux.fromIterable(messages)) + .concatMap(message -> { + return notifyThreadOfNewMessageAsync(newThread, message) + .then(Mono.just(message)); + }) + .then(Mono.just((T) newThread)); + }); + } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java index 9784648b3..5769b5f1f 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java @@ -24,6 +24,7 @@ */ public class ChatMessageContent extends KernelContentImpl { + private String authorName; private final AuthorRole authorRole; @Nullable private final String content; @@ -52,6 +53,28 @@ public ChatMessageContent( null); } + /** + * Creates a new instance of the {@link ChatMessageContent} class. Defaults to + * {@link ChatMessageContentType#TEXT} content type. + * + * @param authorRole the author role that generated the content + * @param authorName the author name + * @param content the content + */ + public ChatMessageContent( + AuthorRole authorRole, + String authorName, + String content) { + this( + authorRole, + authorName, + content, + null, + null, + null, + null); + } + /** * Creates a new instance of the {@link ChatMessageContent} class. Defaults to * {@link ChatMessageContentType#TEXT} content type. @@ -132,6 +155,27 @@ public ChatMessageContent( this.contentType = contentType; } + + /** + * Gets the author name that generated the content + * + * @return the author name that generated the content + */ + @Nullable + public String getAuthorName() { + return authorName; + } + + /** + * Sets the author name that generated the content + * + * @param authorName the author name that generated the content + */ + public void setAuthorName(String authorName) { + this.authorName = authorName; + } + + /** * Gets the author role that generated the content * From 9cfab020f575128f790cdaecf6591cfdba1a1583 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 24 Apr 2025 23:07:19 -0700 Subject: [PATCH 19/46] Remove openai package --- agents/semantickernel-agents-openai/pom.xml | 26 --------------------- 1 file changed, 26 deletions(-) delete mode 100644 agents/semantickernel-agents-openai/pom.xml diff --git a/agents/semantickernel-agents-openai/pom.xml b/agents/semantickernel-agents-openai/pom.xml deleted file mode 100644 index 815a0d5bf..000000000 --- a/agents/semantickernel-agents-openai/pom.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - 4.0.0 - - com.microsoft.semantic-kernel - semantickernel-parent - 1.4.4-SNAPSHOT - - - semantickernel-agents-openai - - - 17 - 17 - UTF-8 - - - - com.microsoft.semantic-kernel - semantickernel-api - - - - \ No newline at end of file From afaa50ce8e018e2cbbf508d1335ee74f866c943f Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 24 Apr 2025 23:08:56 -0700 Subject: [PATCH 20/46] Remove openai package --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index f1536e875..0d31715dd 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,6 @@ data/semantickernel-data-azureaisearch data/semantickernel-data-jdbc data/semantickernel-data-redis - agents/semantickernel-agents-openai agents/semantickernel-agents-core From 3dcbb890cba4e23bec24c83aa4f3d7f1a425736c Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 24 Apr 2025 23:27:05 -0700 Subject: [PATCH 21/46] Add EI_EXPOSE_REP updates --- .../agents/AgentInvokeOptions.java | 32 ++++++++++++++++--- .../agents/AgentResponseItem.java | 14 ++++++++ .../semantickernel/agents/KernelAgent.java | 2 +- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java index d5a99b5ae..00847d159 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java @@ -4,6 +4,7 @@ import com.microsoft.semantickernel.builders.SemanticKernelBuilder; import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.semanticfunctions.KernelArguments; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nullable; @@ -12,7 +13,7 @@ */ public class AgentInvokeOptions { - private final KernelArguments KernelArguments; + private final KernelArguments kernelArguments; private final Kernel kernel; private final String additionalInstructions; private final InvocationContext invocationContext; @@ -27,33 +28,53 @@ public AgentInvokeOptions() { /** * Constructor for AgentInvokeOptions. * - * @param KernelArguments The arguments for the kernel function. + * @param kernelArguments The arguments for the kernel function. * @param kernel The kernel to use. * @param additionalInstructions Additional instructions for the agent. * @param invocationContext The invocation context. */ - public AgentInvokeOptions(@Nullable KernelArguments KernelArguments, + public AgentInvokeOptions(@Nullable KernelArguments kernelArguments, @Nullable Kernel kernel, @Nullable String additionalInstructions, @Nullable InvocationContext invocationContext) { - this.KernelArguments = KernelArguments; + this.kernelArguments = kernelArguments != null ? kernelArguments.copy() : null; this.kernel = kernel; this.additionalInstructions = additionalInstructions; this.invocationContext = invocationContext; } + /** + * Get the kernel arguments. + * + * @return The kernel arguments. + */ public KernelArguments getKernelArguments() { - return KernelArguments; + return kernelArguments; } + /** + * Get the kernel. + * + * @return The kernel. + */ public Kernel getKernel() { return kernel; } + /** + * Get additional instructions. + * + * @return The additional instructions. + */ public String getAdditionalInstructions() { return additionalInstructions; } + /** + * Get the invocation context. + * + * @return The invocation context. + */ public InvocationContext getInvocationContext() { return invocationContext; } @@ -80,6 +101,7 @@ public static class Builder implements SemanticKernelBuilder * @param kernelArguments The kernel arguments. * @return The builder. */ + @SuppressFBWarnings("EI_EXPOSE_REP2") public Builder withKernelArguments(KernelArguments kernelArguments) { this.kernelArguments = kernelArguments; return this; diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java index 61ffdd6d0..f585bfeab 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java @@ -1,18 +1,32 @@ package com.microsoft.semantickernel.agents; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + public class AgentResponseItem { private final T message; private final AgentThread thread; + @SuppressFBWarnings("EI_EXPOSE_REP2") public AgentResponseItem(T message, AgentThread thread) { this.message = message; this.thread = thread; } + /** + * Gets the agent response message. + * + * @return The message. + */ public T getMessage() { return message; } + /** + * Gets the thread. + * + * @return The thread. + */ + @SuppressFBWarnings("EI_EXPOSE_REP") public AgentThread getThread() { return thread; } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java index e5f54a6d6..d70514326 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java @@ -41,7 +41,7 @@ protected KernelAgent( this.name = name; this.description = description; this.kernel = kernel; - this.kernelArguments = kernelArguments; + this.kernelArguments = kernelArguments != null ? kernelArguments.copy() : null; this.invocationContext = invocationContext != null ? invocationContext : InvocationContext.builder().withReturnMode(InvocationReturnMode.FULL_HISTORY).build(); this.instructions = instructions; From 3c0f2557cdc96d1a289af7b7954cb7fdca508fb0 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 24 Apr 2025 23:29:27 -0700 Subject: [PATCH 22/46] Add EI_EXPOSE_REP updates --- .../com/microsoft/semantickernel/agents/AgentInvokeOptions.java | 1 + .../java/com/microsoft/semantickernel/agents/KernelAgent.java | 2 ++ 2 files changed, 3 insertions(+) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java index 00847d159..3fb4cba18 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java @@ -48,6 +48,7 @@ public AgentInvokeOptions(@Nullable KernelArguments kernelArguments, * * @return The kernel arguments. */ + @SuppressFBWarnings("EI_EXPOSE_REP") public KernelArguments getKernelArguments() { return kernelArguments; } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java index d70514326..6731a9279 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java @@ -7,6 +7,7 @@ import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -89,6 +90,7 @@ public Kernel getKernel() { * * @return The invocation context used by the agent */ + @SuppressFBWarnings("EI_EXPOSE_REP") public KernelArguments getKernelArguments() { return kernelArguments; } From fff6b90828cb15682496176e58da5082b3ffe1e7 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 24 Apr 2025 23:35:11 -0700 Subject: [PATCH 23/46] Add EI_EXPOSE_REP updates --- .../agents/chatcompletion/ChatCompletionAgent.java | 2 ++ .../agents/chatcompletion/ChatHistoryAgentThread.java | 3 +++ 2 files changed, 5 insertions(+) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index 2e9a0d7df..ba09bff53 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -19,6 +19,7 @@ import com.microsoft.semantickernel.services.chatcompletion.ChatCompletionService; import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -230,6 +231,7 @@ public Builder withKernel(Kernel kernel) { * * @param KernelArguments The kernel arguments to use. */ + @SuppressFBWarnings("EI_EXPOSE_REP2") public Builder withKernelArguments(KernelArguments KernelArguments) { this.kernelArguments = KernelArguments; return this; diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java index 3aa68ea1b..1a68f8c44 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java @@ -5,6 +5,7 @@ import com.microsoft.semantickernel.builders.SemanticKernelBuilder; import com.microsoft.semantickernel.services.chatcompletion.ChatHistory; import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import reactor.core.publisher.Mono; import javax.annotation.Nonnull; @@ -35,6 +36,7 @@ public ChatHistoryAgentThread(String id, @Nullable ChatHistory chatHistory) { * * @return The chat history. */ + @SuppressFBWarnings("EI_EXPOSE_REP") public ChatHistory getChatHistory() { return chatHistory; } @@ -100,6 +102,7 @@ public Builder withId(String id) { * @param chatHistory The chat history. * @return The builder instance. */ + @SuppressFBWarnings("EI_EXPOSE_REP2") public Builder withChatHistory(ChatHistory chatHistory) { this.chatHistory = chatHistory; return this; From ae917651980f0397dd62bca64754d00fffcbfb36 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Fri, 25 Apr 2025 11:16:35 -0700 Subject: [PATCH 24/46] Make NEW_MESSAGES_ONLY the default for kernel agent invocation context --- .../com/microsoft/semantickernel/agents/KernelAgent.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java index 6731a9279..71e81951d 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java @@ -42,9 +42,10 @@ protected KernelAgent( this.name = name; this.description = description; this.kernel = kernel; - this.kernelArguments = kernelArguments != null ? kernelArguments.copy() : null; + this.kernelArguments = kernelArguments != null + ? kernelArguments.copy() : KernelArguments.builder().build(); this.invocationContext = invocationContext != null - ? invocationContext : InvocationContext.builder().withReturnMode(InvocationReturnMode.FULL_HISTORY).build(); + ? invocationContext : InvocationContext.builder().build(); this.instructions = instructions; this.template = template; } From c004ae05fb658f035b77848e28072cbad59db829 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 28 Apr 2025 09:54:47 -0700 Subject: [PATCH 25/46] Return Mono.error instead of runtime exception --- .../agents/chatcompletion/ChatCompletionAgent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index ba09bff53..82a64334e 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -157,7 +157,7 @@ private Mono>> internalInvokeAsync( ); } catch (ServiceNotFoundException e) { - throw new RuntimeException(e); + return Mono.error(e); } } From 03bd7ed72dc51a6173f0ec8375807a746132c3e1 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 28 Apr 2025 11:36:09 -0700 Subject: [PATCH 26/46] Remove authorName from ChatMessageContent --- .../chatcompletion/ChatCompletionAgent.java | 7 +----- .../chatcompletion/ChatMessageContent.java | 23 ------------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index 82a64334e..f8423f3d7 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -80,12 +80,7 @@ public Mono>>> invokeAsync( ) .flatMapMany(Flux::fromIterable) // notify on the new thread instance - .concatMap(agentMessage -> { - // Set the author name for the message - agentMessage.setAuthorName(this.name); - - return this.notifyThreadOfNewMessageAsync(agentThread, agentMessage).thenReturn(agentMessage); - }) + .concatMap(agentMessage -> this.notifyThreadOfNewMessageAsync(agentThread, agentMessage).thenReturn(agentMessage)) .collectList() .map(chatMessageContents -> chatMessageContents.stream() diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java index 5769b5f1f..0408860e9 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java @@ -23,8 +23,6 @@ * @param the type of the inner content within the messages */ public class ChatMessageContent extends KernelContentImpl { - - private String authorName; private final AuthorRole authorRole; @Nullable private final String content; @@ -155,27 +153,6 @@ public ChatMessageContent( this.contentType = contentType; } - - /** - * Gets the author name that generated the content - * - * @return the author name that generated the content - */ - @Nullable - public String getAuthorName() { - return authorName; - } - - /** - * Sets the author name that generated the content - * - * @param authorName the author name that generated the content - */ - public void setAuthorName(String authorName) { - this.authorName = authorName; - } - - /** * Gets the author role that generated the content * From a19b09fddd661f4d43c8f868be9c009e2d7ec512 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 28 Apr 2025 11:36:09 -0700 Subject: [PATCH 27/46] Remove authorName from ChatMessageContent --- .../chatcompletion/ChatCompletionAgent.java | 7 +----- .../chatcompletion/ChatMessageContent.java | 23 ------------------- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index 82a64334e..f8423f3d7 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -80,12 +80,7 @@ public Mono>>> invokeAsync( ) .flatMapMany(Flux::fromIterable) // notify on the new thread instance - .concatMap(agentMessage -> { - // Set the author name for the message - agentMessage.setAuthorName(this.name); - - return this.notifyThreadOfNewMessageAsync(agentThread, agentMessage).thenReturn(agentMessage); - }) + .concatMap(agentMessage -> this.notifyThreadOfNewMessageAsync(agentThread, agentMessage).thenReturn(agentMessage)) .collectList() .map(chatMessageContents -> chatMessageContents.stream() diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java index 5769b5f1f..0408860e9 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java @@ -23,8 +23,6 @@ * @param the type of the inner content within the messages */ public class ChatMessageContent extends KernelContentImpl { - - private String authorName; private final AuthorRole authorRole; @Nullable private final String content; @@ -155,27 +153,6 @@ public ChatMessageContent( this.contentType = contentType; } - - /** - * Gets the author name that generated the content - * - * @return the author name that generated the content - */ - @Nullable - public String getAuthorName() { - return authorName; - } - - /** - * Sets the author name that generated the content - * - * @param authorName the author name that generated the content - */ - public void setAuthorName(String authorName) { - this.authorName = authorName; - } - - /** * Gets the author role that generated the content * From f1980c2f6b56a9d1b1327f3d766dc0c6fea74f5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 29 Apr 2025 02:06:55 +0000 Subject: [PATCH 28/46] Bump org.springframework.boot:spring-boot Bumps [org.springframework.boot:spring-boot](https://github.com/spring-projects/spring-boot) from 3.3.1 to 3.3.11. - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.1...v3.3.11) --- updated-dependencies: - dependency-name: org.springframework.boot:spring-boot dependency-version: 3.3.11 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- .../semantickernel-demos/semantickernel-spring-starter/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml b/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml index fd9822ebe..bea07af99 100644 --- a/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml +++ b/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml @@ -56,7 +56,7 @@ org.springframework.boot spring-boot - 3.3.1 + 3.3.11 org.springframework From 9b821db80e71b751a50b9880087fe73acdeaed56 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Tue, 29 Apr 2025 09:46:34 -0700 Subject: [PATCH 29/46] Add FunctionChoiceBehavior implementation --- .../chatcompletion/ChatCompletionAgent.java | 7 +- .../chatcompletion/OpenAIChatCompletion.java | 241 +++++++++++++----- .../chatcompletion/OpenAIToolCallConfig.java | 70 +++++ .../agents/CompletionAgent.java | 5 +- .../Example59_OpenAIFunctionCalling.java | 11 +- .../AutoFunctionChoiceBehavior.java | 39 +++ .../FunctionChoiceBehavior.java | 162 ++++++++++++ .../FunctionChoiceBehaviorOptions.java | 49 ++++ .../NoneFunctionChoiceBehavior.java | 15 ++ .../RequiredFunctionChoiceBehavior.java | 19 ++ .../orchestration/FunctionInvocation.java | 29 +++ .../orchestration/InvocationContext.java | 45 +++- .../services/TextAIService.java | 2 +- 13 files changed, 611 insertions(+), 83 deletions(-) create mode 100644 aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/AutoFunctionChoiceBehavior.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehaviorOptions.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java create mode 100644 semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index f8423f3d7..7985f5adf 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -110,19 +110,16 @@ private Mono>> internalInvokeAsync( ? invocationContext.getPromptExecutionSettings() : kernelArguments.getExecutionSettings().get(chatCompletionService.getServiceId()); - ToolCallBehavior toolCallBehavior = invocationContext != null - ? invocationContext.getToolCallBehavior() - : ToolCallBehavior.allowAllKernelFunctions(true); - // Build base invocation context InvocationContext.Builder builder = InvocationContext.builder() .withPromptExecutionSettings(executionSettings) - .withToolCallBehavior(toolCallBehavior) .withReturnMode(InvocationReturnMode.NEW_MESSAGES_ONLY); if (invocationContext != null) { builder = builder .withTelemetry(invocationContext.getTelemetry()) + .withFunctionChoiceBehavior(invocationContext.getFunctionChoiceBehavior()) + .withToolCallBehavior(invocationContext.getToolCallBehavior()) .withContextVariableConverter(invocationContext.getContextVariableTypes()) .withKernelHooks(invocationContext.getKernelHooks()); } diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java index 33f46fc27..0d0dc3045 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java @@ -44,6 +44,10 @@ import com.microsoft.semantickernel.exceptions.AIException.ErrorCodes; import com.microsoft.semantickernel.exceptions.SKCheckedException; import com.microsoft.semantickernel.exceptions.SKException; +import com.microsoft.semantickernel.functionchoice.AutoFunctionChoiceBehavior; +import com.microsoft.semantickernel.functionchoice.FunctionChoiceBehavior; +import com.microsoft.semantickernel.functionchoice.NoneFunctionChoiceBehavior; +import com.microsoft.semantickernel.functionchoice.RequiredFunctionChoiceBehavior; import com.microsoft.semantickernel.hooks.KernelHookEvent; import com.microsoft.semantickernel.hooks.KernelHooks; import com.microsoft.semantickernel.hooks.PostChatCompletionEvent; @@ -196,10 +200,20 @@ public Flux> getStreamingChatMessageContentsAsync( ChatHistory chatHistory, @Nullable Kernel kernel, @Nullable InvocationContext invocationContext) { - if (invocationContext != null && invocationContext.getToolCallBehavior() - .isAutoInvokeAllowed()) { + if (invocationContext != null && + invocationContext.getToolCallBehavior() != null && + invocationContext.getToolCallBehavior().isAutoInvokeAllowed()) { throw new SKException( - "Auto invoke is not supported for streaming chat message contents"); + "ToolCallBehavior auto-invoke is not supported for streaming chat message contents"); + } + + if (invocationContext != null && + invocationContext.getFunctionChoiceBehavior() != null && + invocationContext.getFunctionChoiceBehavior() instanceof AutoFunctionChoiceBehavior && + ((AutoFunctionChoiceBehavior) invocationContext.getFunctionChoiceBehavior()).isAutoInvoke() + ) { + throw new SKException( + "FunctionChoiceBehavior auto-invoke is not supported for streaming chat message contents"); } if (invocationContext != null @@ -219,6 +233,12 @@ public Flux> getStreamingChatMessageContentsAsync( .add(OpenAIFunction.build(function.getMetadata(), plugin.getName())))); } + OpenAIToolCallConfig toolCallConfig = getToolCallConfig( + invocationContext, + functions, + messages.allMessages, + 0); + ChatCompletionsOptions options = executeHook( invocationContext, kernel, @@ -226,8 +246,8 @@ public Flux> getStreamingChatMessageContentsAsync( getCompletionsOptions( this, messages.allMessages, - functions, - invocationContext))) + invocationContext, + toolCallConfig))) .getOptions(); return getClient() @@ -389,16 +409,12 @@ private Mono internalChatMessageContentsAsync( .add(OpenAIFunction.build(function.getMetadata(), plugin.getName())))); } - // Create copy to avoid reactor exceptions when updating request messages internally return internalChatMessageContentsAsync( messages, kernel, functions, invocationContext, - Math.min(MAXIMUM_INFLIGHT_AUTO_INVOKES, - invocationContext != null && invocationContext.getToolCallBehavior() != null - ? invocationContext.getToolCallBehavior().getMaximumAutoInvokeAttempts() - : 0)); + 0); } private Mono internalChatMessageContentsAsync( @@ -406,7 +422,13 @@ private Mono internalChatMessageContentsAsync( @Nullable Kernel kernel, List functions, @Nullable InvocationContext invocationContext, - int autoInvokeAttempts) { + int requestIndex) { + + OpenAIToolCallConfig toolCallConfig = getToolCallConfig( + invocationContext, + functions, + messages.allMessages, + requestIndex); ChatCompletionsOptions options = executeHook( invocationContext, @@ -415,8 +437,8 @@ private Mono internalChatMessageContentsAsync( getCompletionsOptions( this, messages.allMessages, - functions, - invocationContext))) + invocationContext, + toolCallConfig))) .getOptions(); return Mono.deferContextual(contextView -> { @@ -458,9 +480,9 @@ private Mono internalChatMessageContentsAsync( executeHook(invocationContext, kernel, new PostChatCompletionEvent(completions)); // Just return the result: - // If we don't want to attempt to invoke any functions + // If auto-invoking is not enabled // Or if we are auto-invoking, but we somehow end up with other than 1 choice even though only 1 was requested - if (autoInvokeAttempts == 0 || responseMessages.size() != 1) { + if (toolCallConfig == null || !toolCallConfig.isAutoInvoke() || responseMessages.size() != 1) { List> chatMessageContents = getChatMessageContentsAsync( completions); return Mono.just(messages.addChatMessage(chatMessageContents)); @@ -497,14 +519,14 @@ private Mono internalChatMessageContentsAsync( .flatMap(it -> it) .flatMap(msgs -> { return internalChatMessageContentsAsync(msgs, kernel, functions, - invocationContext, autoInvokeAttempts - 1); + invocationContext, requestIndex + 1); }) .onErrorResume(e -> { LOGGER.warn("Tool invocation attempt failed: ", e); // If FunctionInvocationError occurred and there are still attempts left, retry, else exit - if (autoInvokeAttempts > 0) { + if (requestIndex > 0) { ChatMessages currentMessages = messages; if (e instanceof FunctionInvocationError) { currentMessages.assertCommonHistory( @@ -518,7 +540,7 @@ private Mono internalChatMessageContentsAsync( kernel, functions, invocationContext, - autoInvokeAttempts - 1); + requestIndex + 1); } else { return Mono.error(e); } @@ -860,8 +882,8 @@ private List formOpenAiToolCalls( private static ChatCompletionsOptions getCompletionsOptions( ChatCompletionService chatCompletionService, List chatRequestMessages, - @Nullable List functions, - @Nullable InvocationContext invocationContext) { + @Nullable InvocationContext invocationContext, + @Nullable OpenAIToolCallConfig toolCallConfig) { chatRequestMessages = chatRequestMessages .stream() @@ -871,12 +893,13 @@ private static ChatCompletionsOptions getCompletionsOptions( ChatCompletionsOptions options = new ChatCompletionsOptions(chatRequestMessages) .setModel(chatCompletionService.getModelId()); - if (invocationContext != null && invocationContext.getToolCallBehavior() != null) { - configureToolCallBehaviorOptions( - options, - invocationContext.getToolCallBehavior(), - functions, - chatRequestMessages); + if (toolCallConfig != null) { + options.setTools(toolCallConfig.getTools()); + options.setToolChoice(toolCallConfig.getToolChoice()); + + if (toolCallConfig.getOptions() != null) { + options.setParallelToolCalls(toolCallConfig.getOptions().isParallelCallsAllowed()); + } } PromptExecutionSettings promptExecutionSettings = invocationContext != null @@ -946,92 +969,176 @@ private static ChatCompletionsOptions getCompletionsOptions( return options; } - private static void configureToolCallBehaviorOptions( - ChatCompletionsOptions options, + private static OpenAIToolCallConfig getToolCallConfig( + @Nullable InvocationContext invocationContext, + @Nullable List functions, + List chatRequestMessages, + int requestIndex) { + + if (invocationContext == null || functions == null || functions.isEmpty()) { + return null; + } + + if (invocationContext.getFunctionChoiceBehavior() == null && invocationContext.getToolCallBehavior() == null) { + return null; + } + + + if (invocationContext.getFunctionChoiceBehavior() != null) { + return getFunctionChoiceBehaviorConfig( + invocationContext.getFunctionChoiceBehavior(), + functions, + requestIndex); + } else { + return getToolCallBehaviorConfig( + invocationContext.getToolCallBehavior(), + functions, + chatRequestMessages, + requestIndex); + } + } + + private static OpenAIToolCallConfig getFunctionChoiceBehaviorConfig( + @Nullable FunctionChoiceBehavior functionChoiceBehavior, + @Nullable List functions, + int requestIndex) { + if (functionChoiceBehavior == null) { + return null; + } + + if (functions == null || functions.isEmpty()) { + return null; + } + + ChatCompletionsToolSelection toolChoice; + boolean autoInvoke; + + if (functionChoiceBehavior instanceof RequiredFunctionChoiceBehavior) { + // After first request a required function must have been called already + if (requestIndex >= 1) { + return null; + } + + toolChoice = new ChatCompletionsToolSelection(ChatCompletionsToolSelectionPreset.REQUIRED); + autoInvoke = ((RequiredFunctionChoiceBehavior) functionChoiceBehavior).isAutoInvoke(); + } else if (functionChoiceBehavior instanceof AutoFunctionChoiceBehavior) { + toolChoice = new ChatCompletionsToolSelection(ChatCompletionsToolSelectionPreset.AUTO); + autoInvoke = ((AutoFunctionChoiceBehavior) functionChoiceBehavior).isAutoInvoke() && requestIndex < MAXIMUM_INFLIGHT_AUTO_INVOKES; + } else if (functionChoiceBehavior instanceof NoneFunctionChoiceBehavior) { + toolChoice = new ChatCompletionsToolSelection(ChatCompletionsToolSelectionPreset.NONE); + autoInvoke = false; + } else { + throw new SKException( + "Unsupported function choice behavior: " + functionChoiceBehavior); + } + + // List of functions advertised to the model + List toolDefinitions = functions.stream() + .filter(function -> functionChoiceBehavior.isFunctionAllowed(function.getPluginName(), function.getName())) + .map(OpenAIFunction::getFunctionDefinition) + .map(it -> new ChatCompletionsFunctionToolDefinitionFunction(it.getName()) + .setDescription(it.getDescription()) + .setParameters(it.getParameters())) + .map(ChatCompletionsFunctionToolDefinition::new) + .collect(Collectors.toList()); + + return new OpenAIToolCallConfig( + toolDefinitions, + toolChoice, + autoInvoke, + functionChoiceBehavior.getOptions()); + } + + private static OpenAIToolCallConfig getToolCallBehaviorConfig( @Nullable ToolCallBehavior toolCallBehavior, @Nullable List functions, - List chatRequestMessages) { + List chatRequestMessages, + int requestIndex) { if (toolCallBehavior == null) { - return; + return null; } if (functions == null || functions.isEmpty()) { - return; + return null; } + List toolDefinitions; + ChatCompletionsToolSelection toolChoice; + // If a specific function is required to be called if (toolCallBehavior instanceof ToolCallBehavior.RequiredKernelFunction) { - KernelFunction toolChoice = ((ToolCallBehavior.RequiredKernelFunction) toolCallBehavior) + KernelFunction requiredFunction = ((ToolCallBehavior.RequiredKernelFunction) toolCallBehavior) .getRequiredFunction(); String toolChoiceName = String.format("%s%s%s", - toolChoice.getPluginName(), + requiredFunction.getPluginName(), OpenAIFunction.getNameSeparator(), - toolChoice.getName()); + requiredFunction.getName()); // If required tool call has already been called dont ask for it again boolean hasBeenExecuted = hasToolCallBeenExecuted(chatRequestMessages, toolChoiceName); if (hasBeenExecuted) { - return; + return null; } - List toolDefinitions = new ArrayList<>(); - FunctionDefinition function = OpenAIFunction.toFunctionDefinition( - toolChoice.getMetadata(), - toolChoice.getPluginName()); + requiredFunction.getMetadata(), + requiredFunction.getPluginName()); + toolDefinitions = new ArrayList<>(); toolDefinitions.add(new ChatCompletionsFunctionToolDefinition( new ChatCompletionsFunctionToolDefinitionFunction(function.getName()) .setDescription(function.getDescription()) .setParameters(function.getParameters()))); - options.setTools(toolDefinitions); try { String json = String.format( "{\"type\":\"function\",\"function\":{\"name\":\"%s\"}}", toolChoiceName); - options.setToolChoice( - new ChatCompletionsToolSelection( + toolChoice = new ChatCompletionsToolSelection( ChatCompletionsNamedToolSelection.fromJson( DefaultJsonReader.fromString( json, - new JsonOptions())))); + new JsonOptions()))); } catch (JsonProcessingException e) { throw SKException.build("Failed to parse tool choice", e); } catch (IOException e) { throw new SKException(e); } - return; } - // If a set of functions are enabled to be called - ToolCallBehavior.AllowedKernelFunctions enabledKernelFunctions = (ToolCallBehavior.AllowedKernelFunctions) toolCallBehavior; - List toolDefinitions = functions.stream() - .filter(function -> { - // check if all kernel functions are enabled - if (enabledKernelFunctions.isAllKernelFunctionsAllowed()) { - return true; - } - // otherwise, check for the specific function - return enabledKernelFunctions.isFunctionAllowed(function.getPluginName(), - function.getName()); - }) - .map(OpenAIFunction::getFunctionDefinition) - .map(it -> new ChatCompletionsFunctionToolDefinitionFunction(it.getName()) - .setDescription(it.getDescription()) - .setParameters(it.getParameters())) - .map(it -> new ChatCompletionsFunctionToolDefinition(it)) - .collect(Collectors.toList()); + else { + toolChoice = new ChatCompletionsToolSelection(ChatCompletionsToolSelectionPreset.AUTO); + + ToolCallBehavior.AllowedKernelFunctions enabledKernelFunctions = (ToolCallBehavior.AllowedKernelFunctions) toolCallBehavior; + toolDefinitions = functions.stream() + .filter(function -> { + // check if all kernel functions are enabled + if (enabledKernelFunctions.isAllKernelFunctionsAllowed()) { + return true; + } + // otherwise, check for the specific function + return enabledKernelFunctions.isFunctionAllowed(function.getPluginName(), + function.getName()); + }) + .map(OpenAIFunction::getFunctionDefinition) + .map(it -> new ChatCompletionsFunctionToolDefinitionFunction(it.getName()) + .setDescription(it.getDescription()) + .setParameters(it.getParameters())) + .map(ChatCompletionsFunctionToolDefinition::new) + .collect(Collectors.toList()); - if (toolDefinitions.isEmpty()) { - return; + if (toolDefinitions.isEmpty()) { + return null; + } } - options.setTools(toolDefinitions); - options.setToolChoice( - new ChatCompletionsToolSelection(ChatCompletionsToolSelectionPreset.AUTO)); + return new OpenAIToolCallConfig( + toolDefinitions, + toolChoice, + toolCallBehavior.isAutoInvokeAllowed() && requestIndex < Math.min(MAXIMUM_INFLIGHT_AUTO_INVOKES, toolCallBehavior.getMaximumAutoInvokeAttempts()), + null); } private static boolean hasToolCallBeenExecuted(List chatRequestMessages, diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java new file mode 100644 index 000000000..895252d3a --- /dev/null +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java @@ -0,0 +1,70 @@ +package com.microsoft.semantickernel.aiservices.openai.chatcompletion; + +import com.azure.ai.openai.models.ChatCompletionsToolDefinition; +import com.azure.ai.openai.models.ChatCompletionsToolSelection; +import com.microsoft.semantickernel.functionchoice.FunctionChoiceBehaviorOptions; + +import javax.annotation.Nullable; +import java.util.List; + +public class OpenAIToolCallConfig { + private final List tools; + private final ChatCompletionsToolSelection toolChoice; + private final boolean autoInvoke; + private final FunctionChoiceBehaviorOptions options; + + /** + * Creates a new instance of the {@link OpenAIToolCallConfig} class. + * + * @param tools The list of tools available for the call. + * @param toolChoice The tool selection strategy. + * @param autoInvoke Indicates whether to automatically invoke the tool. + * @param options Additional options for function choice behavior. + */ + public OpenAIToolCallConfig( + List tools, + ChatCompletionsToolSelection toolChoice, + boolean autoInvoke, + @Nullable FunctionChoiceBehaviorOptions options) { + this.tools = tools; + this.toolChoice = toolChoice; + this.autoInvoke = autoInvoke; + this.options = options; + } + + /** + * Gets the list of tools available for the call. + * + * @return The list of tools. + */ + public List getTools() { + return tools; + } + + /** + * Gets the tool selection strategy. + * + * @return The tool selection strategy. + */ + public ChatCompletionsToolSelection getToolChoice() { + return toolChoice; + } + + /** + * Indicates whether to automatically invoke the tool. + * + * @return True if auto-invocation is enabled; otherwise, false. + */ + public boolean isAutoInvoke() { + return autoInvoke; + } + + /** + * Gets additional options for function choice behavior. + * + * @return The function choice behavior options. + */ + public FunctionChoiceBehaviorOptions getOptions() { + return options; + } +} diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java index 1e5a665a9..16941ee41 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java @@ -10,11 +10,10 @@ import com.microsoft.semantickernel.agents.chatcompletion.ChatHistoryAgentThread; import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter; -import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; +import com.microsoft.semantickernel.functionchoice.FunctionChoiceBehavior; import com.microsoft.semantickernel.implementation.templateengine.tokenizer.DefaultPromptTemplate; import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; -import com.microsoft.semantickernel.orchestration.ToolCallBehavior; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.github.GitHubModel; import com.microsoft.semantickernel.samples.plugins.github.GitHubPlugin; @@ -68,7 +67,7 @@ public static void main(String[] args) { .build(); InvocationContext invocationContext = InvocationContext.builder() - .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) + .withFunctionChoiceBehavior(FunctionChoiceBehavior.auto(true)) .withContextVariableConverter(new ContextVariableTypeConverter<>( GitHubModel.Issue.class, o -> (GitHubModel.Issue) o, diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example59_OpenAIFunctionCalling.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example59_OpenAIFunctionCalling.java index e52c2be79..e921bb784 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example59_OpenAIFunctionCalling.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/functions/Example59_OpenAIFunctionCalling.java @@ -10,6 +10,7 @@ import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatMessageContent; import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIFunctionToolCall; import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; +import com.microsoft.semantickernel.functionchoice.FunctionChoiceBehavior; import com.microsoft.semantickernel.implementation.CollectionUtil; import com.microsoft.semantickernel.orchestration.FunctionResult; import com.microsoft.semantickernel.orchestration.FunctionResultMetadata; @@ -38,7 +39,7 @@ public class Example59_OpenAIFunctionCalling { // Only required if AZURE_CLIENT_KEY is set private static final String CLIENT_ENDPOINT = System.getenv("CLIENT_ENDPOINT"); private static final String MODEL_ID = System.getenv() - .getOrDefault("MODEL_ID", "gpt-35-turbo-2"); + .getOrDefault("MODEL_ID", "gpt-4o"); // Define functions that can be called by the model public static class HelperFunctions { @@ -118,7 +119,7 @@ public static void main(String[] args) throws NoSuchMethodException { var result = kernel .invokeAsync(function) - .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) + .withFunctionChoiceBehavior(FunctionChoiceBehavior.auto(true)) .withResultType(ContextVariableTypes.getGlobalVariableTypeForClass(String.class)) .block(); System.out.println(result.getResult()); @@ -134,7 +135,7 @@ public static void main(String[] args) throws NoSuchMethodException { chatHistory, kernel, InvocationContext.builder() - .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(false)) + .withFunctionChoiceBehavior(FunctionChoiceBehavior.auto(false)) .withReturnMode(InvocationReturnMode.FULL_HISTORY) .build()) .block(); @@ -243,7 +244,7 @@ public static void multiTurnaroundCall() { chatHistory, kernel, InvocationContext.builder() - .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) + .withFunctionChoiceBehavior(FunctionChoiceBehavior.auto(true)) .withReturnMode(InvocationReturnMode.FULL_HISTORY) .build()) .block(); @@ -258,7 +259,7 @@ public static void multiTurnaroundCall() { chatHistory, kernel, InvocationContext.builder() - .withToolCallBehavior(ToolCallBehavior.allowAllKernelFunctions(true)) + .withFunctionChoiceBehavior(FunctionChoiceBehavior.auto(true)) .withReturnMode(InvocationReturnMode.FULL_HISTORY) .build()) .block(); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/AutoFunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/AutoFunctionChoiceBehavior.java new file mode 100644 index 000000000..3e3878b76 --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/AutoFunctionChoiceBehavior.java @@ -0,0 +1,39 @@ +package com.microsoft.semantickernel.functionchoice; + +import com.microsoft.semantickernel.semanticfunctions.KernelFunction; + +import javax.annotation.Nullable; +import java.util.List; + +/** + * A set of allowed kernel functions. All kernel functions are allowed if allKernelFunctionsAllowed is true. + * Otherwise, only the functions in allowedFunctions are allowed. + *

+ * If a function is allowed, it may be called. If it is not allowed, it will not be called. + */ +public class AutoFunctionChoiceBehavior extends FunctionChoiceBehavior { + private final boolean autoInvoke; + + /** + * Create a new instance of AutoFunctionChoiceBehavior. + * + * @param autoInvoke Whether auto-invocation is enabled. + * @param functions A set of functions to advertise to the model. + * @param options Options for the function choice behavior. + */ + public AutoFunctionChoiceBehavior(boolean autoInvoke, + @Nullable List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { + super(functions, options); + this.autoInvoke = autoInvoke; + } + + /** + * Check whether the given function is allowed. + * + * @return Whether the function is allowed. + */ + public boolean isAutoInvoke() { + return autoInvoke; + } +} \ No newline at end of file diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java new file mode 100644 index 000000000..5e4c50cd4 --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java @@ -0,0 +1,162 @@ +// Copyright (c) Microsoft. All rights reserved. +package com.microsoft.semantickernel.functionchoice; + +import com.microsoft.semantickernel.semanticfunctions.KernelFunction; + +import javax.annotation.Nullable; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +/** + * Defines the behavior of a tool call. Currently, the only tool available is function calling. + */ +public abstract class FunctionChoiceBehavior { + private final Set fullFunctionNames; + + protected final List> functions; + protected final FunctionChoiceBehaviorOptions options; + + protected FunctionChoiceBehavior(List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { + this.functions = functions; + this.fullFunctionNames = new HashSet<>(); + + if (functions != null) { + functions.stream().filter(Objects::nonNull).forEach( + f -> this.fullFunctionNames + .add(formFullFunctionName(f.getPluginName(), f.getName()))); + } + + if (options != null) { + this.options = options; + } else { + this.options = FunctionChoiceBehaviorOptions.builder().build(); + } + } + + /** + * Gets the functions that are allowed. + * + * @return The functions that are allowed. + */ + public List> getFunctions() { + return functions; + } + + /** + * Gets the options for the function choice behavior. + * + * @return The options for the function choice behavior. + */ + public FunctionChoiceBehaviorOptions getOptions() { + return options; + } + + /** + * Gets an instance of the FunctionChoiceBehavior that provides all the Kernel's plugins functions to the AI model to call. + * + * @param autoInvoke Indicates whether the functions should be automatically invoked by AI connectors + * + * @return A new ToolCallBehavior instance with all kernel functions allowed. + */ + public static FunctionChoiceBehavior auto(boolean autoInvoke) { + return new AutoFunctionChoiceBehavior(autoInvoke, null, null); + } + + /** + * Gets an instance of the FunctionChoiceBehavior that provides either all the Kernel's plugins functions to the AI model to call or specific functions. + * + * @param autoInvoke Enable or disable auto-invocation. + * If auto-invocation is enabled, the model may request that the Semantic Kernel + * invoke the kernel functions and return the value to the model. + * @param functions Functions to provide to the model. If null, all the Kernel's plugins' functions are provided to the model. + * If empty, no functions are provided to the model, which is equivalent to disabling function calling. + * @param options Options for the function choice behavior. + * + * @return A new FunctionChoiceBehavior instance with all kernel functions allowed. + */ + public static FunctionChoiceBehavior auto(boolean autoInvoke, + List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { + return new AutoFunctionChoiceBehavior(autoInvoke, functions, options); + } + + /** + * Gets an instance of the FunctionChoiceBehavior that provides either all the Kernel's plugins functions to the AI model to call or specific functions. + *

+ * This behavior forces the model to call the provided functions. + * SK connectors will invoke a requested function or multiple requested functions if the model requests multiple ones in one request, + * while handling the first request, and stop advertising the functions for the following requests to prevent the model from repeatedly calling the same function(s). + * + * @param functions Functions to provide to the model. If null, all the Kernel's plugins' functions are provided to the model. + * If empty, no functions are provided to the model, which is equivalent to disabling function calling. + * @return A new FunctionChoiceBehavior instance with the required function. + */ + public static FunctionChoiceBehavior required(boolean autoInvoke, + List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { + return new RequiredFunctionChoiceBehavior(autoInvoke, functions, options); + } + + /** + * Gets an instance of the FunctionChoiceBehavior that provides either all the Kernel's plugins functions to the AI model to call or specific functions. + *

+ * This behavior is useful if the user should first validate what functions the model will use. + * + * @param functions Functions to provide to the model. If null, all the Kernel's plugins' functions are provided to the model. + * If empty, no functions are provided to the model, which is equivalent to disabling function calling. + */ + public static FunctionChoiceBehavior none(List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { + return new NoneFunctionChoiceBehavior(functions, options); + } + + + /** + * The separator between the plugin name and the function name. + */ + public static final String FUNCTION_NAME_SEPARATOR = "-"; + + /** + * Form the full function name. + * + * @param pluginName The name of the plugin that the function is in. + * @param functionName The name of the function. + * @return The key for the function. + */ + public static String formFullFunctionName(@Nullable String pluginName, String functionName) { + if (pluginName == null) { + pluginName = ""; + } + return String.format("%s%s%s", pluginName, FUNCTION_NAME_SEPARATOR, functionName); + } + + /** + * Check whether the given function is allowed. + * + * @param function The function to check. + * @return Whether the function is allowed. + */ + public boolean isFunctionAllowed(KernelFunction function) { + return isFunctionAllowed(function.getPluginName(), function.getName()); + } + + /** + * Check whether the given function is allowed. + * + * @param pluginName The name of the plugin that the function is in. + * @param functionName The name of the function. + * @return Whether the function is allowed. + */ + public boolean isFunctionAllowed(@Nullable String pluginName, String functionName) { + // If no functions are provided, all functions are allowed. + if (functions == null || functions.isEmpty()) { + return true; + } + + String key = formFullFunctionName(pluginName, functionName); + return fullFunctionNames.contains(key); + } +} diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehaviorOptions.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehaviorOptions.java new file mode 100644 index 000000000..bbde7c578 --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehaviorOptions.java @@ -0,0 +1,49 @@ +package com.microsoft.semantickernel.functionchoice; + +import com.microsoft.semantickernel.builders.SemanticKernelBuilder; + +public class FunctionChoiceBehaviorOptions { + private final boolean parallelCallsAllowed; + + private FunctionChoiceBehaviorOptions(boolean parallelCallsAllowed) { + this.parallelCallsAllowed = parallelCallsAllowed; + } + + /** + * Returns a new builder for {@link FunctionChoiceBehaviorOptions}. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Indicates whether parallel calls to functions are allowed. + * + * @return True if parallel calls are allowed; otherwise, false. + */ + public boolean isParallelCallsAllowed() { + return parallelCallsAllowed; + } + + /** + * Builder for {@link FunctionChoiceBehaviorOptions}. + */ + public static class Builder implements SemanticKernelBuilder { + private boolean allowParallelCalls = false; + + /** + * Sets whether parallel calls to functions are allowed. + * + * @param allowParallelCalls True if parallel calls are allowed; otherwise, false. + * @return The builder instance. + */ + public Builder withParallelCallsAllowed(boolean allowParallelCalls) { + this.allowParallelCalls = allowParallelCalls; + return this; + } + + public FunctionChoiceBehaviorOptions build() { + return new FunctionChoiceBehaviorOptions(allowParallelCalls); + } + } +} diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java new file mode 100644 index 000000000..0ee7f1a01 --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java @@ -0,0 +1,15 @@ +package com.microsoft.semantickernel.functionchoice; + +import com.microsoft.semantickernel.semanticfunctions.KernelFunction; + +import java.util.List; + +public class NoneFunctionChoiceBehavior extends FunctionChoiceBehavior { + + /** + * Create a new instance of NoneFunctionChoiceBehavior. + */ + public NoneFunctionChoiceBehavior(List> functions, FunctionChoiceBehaviorOptions options) { + super(functions, options); + } +} diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java new file mode 100644 index 000000000..57312b0fb --- /dev/null +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java @@ -0,0 +1,19 @@ +package com.microsoft.semantickernel.functionchoice; + +import com.microsoft.semantickernel.semanticfunctions.KernelFunction; + +import java.util.List; + +public class RequiredFunctionChoiceBehavior extends AutoFunctionChoiceBehavior { + + /** + * Create a new instance of RequiredFunctionChoiceBehavior. + * + * @param autoInvoke Whether auto-invocation is enabled. + * @param functions A set of functions to advertise to the model. + * @param options Options for the function choice behavior. + */ + public RequiredFunctionChoiceBehavior(boolean autoInvoke, List> functions, FunctionChoiceBehaviorOptions options) { + super(autoInvoke, functions, options); + } +} diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java index 0ae16e194..9b8a518c3 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/FunctionInvocation.java @@ -8,6 +8,7 @@ import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.contextvariables.converters.ContextVariableJacksonConverter; import com.microsoft.semantickernel.exceptions.SKException; +import com.microsoft.semantickernel.functionchoice.FunctionChoiceBehavior; import com.microsoft.semantickernel.hooks.KernelHook; import com.microsoft.semantickernel.hooks.KernelHooks; import com.microsoft.semantickernel.hooks.KernelHooks.UnmodifiableKernelHooks; @@ -48,6 +49,9 @@ public class FunctionInvocation extends Mono> { protected PromptExecutionSettings promptExecutionSettings; @Nullable protected ToolCallBehavior toolCallBehavior; + @Nullable + protected FunctionChoiceBehavior functionChoiceBehavior; + @Nullable protected SemanticKernelTelemetry telemetry; @@ -196,6 +200,7 @@ public FunctionInvocation withResultType(ContextVariableType resultTyp .withArguments(arguments) .addKernelHooks(hooks) .withPromptExecutionSettings(promptExecutionSettings) + .withFunctionChoiceBehavior(functionChoiceBehavior) .withToolCallBehavior(toolCallBehavior) .withTypes(contextVariableTypes); } @@ -287,10 +292,32 @@ public FunctionInvocation withPromptExecutionSettings( */ public FunctionInvocation withToolCallBehavior(@Nullable ToolCallBehavior toolCallBehavior) { logSubscribeWarning(); + if (toolCallBehavior != null && functionChoiceBehavior != null) { + throw new SKException( + "ToolCallBehavior cannot be set when FunctionChoiceBehavior is set."); + } this.toolCallBehavior = toolCallBehavior; return this; } + /** + * Supply function choice behavior to the function invocation. + * + * @param functionChoiceBehavior The function choice behavior to supply to the function + * invocation. + * @return this {@code FunctionInvocation} for fluent chaining. + */ + public FunctionInvocation withFunctionChoiceBehavior( + @Nullable FunctionChoiceBehavior functionChoiceBehavior) { + if (functionChoiceBehavior != null && toolCallBehavior != null) { + throw new SKException( + "FunctionChoiceBehavior cannot be set when ToolCallBehavior is set."); + } + logSubscribeWarning(); + this.functionChoiceBehavior = functionChoiceBehavior; + return this; + } + /** * Supply a type converter to the function invocation. * @@ -340,6 +367,7 @@ public FunctionInvocation withInvocationContext( } logSubscribeWarning(); withTypes(invocationContext.getContextVariableTypes()); + withFunctionChoiceBehavior(invocationContext.getFunctionChoiceBehavior()); withToolCallBehavior(invocationContext.getToolCallBehavior()); withPromptExecutionSettings(invocationContext.getPromptExecutionSettings()); addKernelHooks(invocationContext.getKernelHooks()); @@ -387,6 +415,7 @@ public void subscribe(CoreSubscriber> coreSubscriber) hooks, promptExecutionSettings, toolCallBehavior, + functionChoiceBehavior, contextVariableTypes, InvocationReturnMode.NEW_MESSAGES_ONLY, telemetry)); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java index 6fd3f0d21..48c10949c 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java @@ -4,6 +4,8 @@ import com.microsoft.semantickernel.builders.SemanticKernelBuilder; import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter; import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; +import com.microsoft.semantickernel.exceptions.SKException; +import com.microsoft.semantickernel.functionchoice.FunctionChoiceBehavior; import com.microsoft.semantickernel.hooks.KernelHooks; import com.microsoft.semantickernel.hooks.KernelHooks.UnmodifiableKernelHooks; import com.microsoft.semantickernel.implementation.telemetry.SemanticKernelTelemetry; @@ -23,6 +25,8 @@ public class InvocationContext { private final PromptExecutionSettings promptExecutionSettings; @Nullable private final ToolCallBehavior toolCallBehavior; + @Nullable + private final FunctionChoiceBehavior functionChoiceBehavior; private final ContextVariableTypes contextVariableTypes; private final InvocationReturnMode invocationReturnMode; private final SemanticKernelTelemetry telemetry; @@ -39,12 +43,14 @@ protected InvocationContext( @Nullable KernelHooks hooks, @Nullable PromptExecutionSettings promptExecutionSettings, @Nullable ToolCallBehavior toolCallBehavior, + @Nullable FunctionChoiceBehavior functionChoiceBehavior, @Nullable ContextVariableTypes contextVariableTypes, InvocationReturnMode invocationReturnMode, SemanticKernelTelemetry telemetry) { this.hooks = unmodifiableClone(hooks); this.promptExecutionSettings = promptExecutionSettings; this.toolCallBehavior = toolCallBehavior; + this.functionChoiceBehavior = functionChoiceBehavior; this.invocationReturnMode = invocationReturnMode; if (contextVariableTypes == null) { this.contextVariableTypes = new ContextVariableTypes(); @@ -61,6 +67,7 @@ protected InvocationContext() { this.hooks = null; this.promptExecutionSettings = null; this.toolCallBehavior = null; + this.functionChoiceBehavior = null; this.contextVariableTypes = new ContextVariableTypes(); this.invocationReturnMode = InvocationReturnMode.NEW_MESSAGES_ONLY; this.telemetry = null; @@ -76,6 +83,7 @@ protected InvocationContext(@Nullable InvocationContext context) { this.hooks = null; this.promptExecutionSettings = null; this.toolCallBehavior = null; + this.functionChoiceBehavior = null; this.contextVariableTypes = new ContextVariableTypes(); this.invocationReturnMode = InvocationReturnMode.NEW_MESSAGES_ONLY; this.telemetry = null; @@ -83,6 +91,7 @@ protected InvocationContext(@Nullable InvocationContext context) { this.hooks = context.hooks; this.promptExecutionSettings = context.promptExecutionSettings; this.toolCallBehavior = context.toolCallBehavior; + this.functionChoiceBehavior = context.functionChoiceBehavior; this.contextVariableTypes = context.contextVariableTypes; this.invocationReturnMode = context.invocationReturnMode; this.telemetry = context.telemetry; @@ -156,6 +165,16 @@ public ToolCallBehavior getToolCallBehavior() { return toolCallBehavior; } + /** + * Get the behavior for function choice. + * + * @return The behavior for function choice. + */ + @Nullable + public FunctionChoiceBehavior getFunctionChoiceBehavior() { + return functionChoiceBehavior; + } + /** * Get the types of context variables. * @@ -190,6 +209,8 @@ public static class Builder implements SemanticKernelBuilder private PromptExecutionSettings promptExecutionSettings; @Nullable private ToolCallBehavior toolCallBehavior; + @Nullable + private FunctionChoiceBehavior functionChoiceBehavior; private InvocationReturnMode invocationReturnMode = InvocationReturnMode.NEW_MESSAGES_ONLY; @Nullable private SemanticKernelTelemetry telemetry; @@ -226,10 +247,30 @@ public Builder withPromptExecutionSettings( */ public Builder withToolCallBehavior( @Nullable ToolCallBehavior toolCallBehavior) { + if (toolCallBehavior != null && functionChoiceBehavior != null) { + throw new SKException( + "ToolCallBehavior cannot be set when FunctionChoiceBehavior is set."); + } this.toolCallBehavior = toolCallBehavior; return this; } + /** + * Add function choice behavior to the builder. + * + * @param functionChoiceBehavior the behavior to add. + * @return this {@link Builder} + */ + public Builder withFunctionChoiceBehavior( + @Nullable FunctionChoiceBehavior functionChoiceBehavior) { + if (functionChoiceBehavior != null && toolCallBehavior != null) { + throw new SKException( + "FunctionChoiceBehavior cannot be set when ToolCallBehavior is set."); + } + this.functionChoiceBehavior = functionChoiceBehavior; + return this; + } + /** * Add a context variable type converter to the builder. * @@ -269,7 +310,7 @@ public Builder withReturnMode(InvocationReturnMode invocationReturnMode) { /** * Add a tracer to the builder. * - * @param tracer the tracer to add. + * @param telemetry the tracer to add. * @return this {@link Builder} */ public Builder withTelemetry(@Nullable SemanticKernelTelemetry telemetry) { @@ -282,7 +323,7 @@ public InvocationContext build() { if (telemetry == null) { telemetry = new SemanticKernelTelemetry(); } - return new InvocationContext(hooks, promptExecutionSettings, toolCallBehavior, + return new InvocationContext(hooks, promptExecutionSettings, toolCallBehavior, functionChoiceBehavior, contextVariableTypes, invocationReturnMode, telemetry); } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/TextAIService.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/TextAIService.java index 09b3ea1fe..3eee32d36 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/TextAIService.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/TextAIService.java @@ -29,5 +29,5 @@ public interface TextAIService extends AIService { * future and/or made configurable should need arise. *

*/ - int MAXIMUM_INFLIGHT_AUTO_INVOKES = 5; + int MAXIMUM_INFLIGHT_AUTO_INVOKES = 128; } From bc618869e76dec1927b0a9624a6a8737644f89e9 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Tue, 29 Apr 2025 10:04:55 -0700 Subject: [PATCH 30/46] return Collections.unmodifiableList(functions) --- .../functionchoice/FunctionChoiceBehavior.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java index 5e4c50cd4..844e66a54 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java @@ -4,6 +4,7 @@ import com.microsoft.semantickernel.semanticfunctions.KernelFunction; import javax.annotation.Nullable; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -20,7 +21,7 @@ public abstract class FunctionChoiceBehavior { protected FunctionChoiceBehavior(List> functions, @Nullable FunctionChoiceBehaviorOptions options) { - this.functions = functions; + this.functions = functions != null ? Collections.unmodifiableList(functions) : null; this.fullFunctionNames = new HashSet<>(); if (functions != null) { @@ -42,7 +43,7 @@ protected FunctionChoiceBehavior(List> functions, * @return The functions that are allowed. */ public List> getFunctions() { - return functions; + return Collections.unmodifiableList(functions); } /** From 8cd72afadf25ca5ec31458707c0f42f78c0fdb4f Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Tue, 29 Apr 2025 10:20:39 -0700 Subject: [PATCH 31/46] Fixes --- .../openai/chatcompletion/OpenAIToolCallConfig.java | 5 ++++- .../functionchoice/FunctionChoiceBehavior.java | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java index 895252d3a..4694d2f8b 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java @@ -3,8 +3,10 @@ import com.azure.ai.openai.models.ChatCompletionsToolDefinition; import com.azure.ai.openai.models.ChatCompletionsToolSelection; import com.microsoft.semantickernel.functionchoice.FunctionChoiceBehaviorOptions; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.Nullable; +import java.util.Collections; import java.util.List; public class OpenAIToolCallConfig { @@ -21,6 +23,7 @@ public class OpenAIToolCallConfig { * @param autoInvoke Indicates whether to automatically invoke the tool. * @param options Additional options for function choice behavior. */ + @SuppressFBWarnings("EI_EXPOSE_REP2") public OpenAIToolCallConfig( List tools, ChatCompletionsToolSelection toolChoice, @@ -38,7 +41,7 @@ public OpenAIToolCallConfig( * @return The list of tools. */ public List getTools() { - return tools; + return Collections.unmodifiableList(tools); } /** diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java index 844e66a54..bfa397856 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java @@ -19,7 +19,7 @@ public abstract class FunctionChoiceBehavior { protected final List> functions; protected final FunctionChoiceBehaviorOptions options; - protected FunctionChoiceBehavior(List> functions, + protected FunctionChoiceBehavior(@Nullable List> functions, @Nullable FunctionChoiceBehaviorOptions options) { this.functions = functions != null ? Collections.unmodifiableList(functions) : null; this.fullFunctionNames = new HashSet<>(); From a222ccb427f5b73f8bb467fc65656daee933281a Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Tue, 29 Apr 2025 10:27:16 -0700 Subject: [PATCH 32/46] Fix retry logic --- .../aiservices/openai/chatcompletion/OpenAIChatCompletion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java index 0d0dc3045..20be752eb 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java @@ -526,7 +526,7 @@ private Mono internalChatMessageContentsAsync( LOGGER.warn("Tool invocation attempt failed: ", e); // If FunctionInvocationError occurred and there are still attempts left, retry, else exit - if (requestIndex > 0) { + if (requestIndex < MAXIMUM_INFLIGHT_AUTO_INVOKES) { ChatMessages currentMessages = messages; if (e instanceof FunctionInvocationError) { currentMessages.assertCommonHistory( From 3c3953818a01d6085ebc2ebfca3ade7088ba56e2 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Wed, 30 Apr 2025 12:25:21 -0700 Subject: [PATCH 33/46] Add suggestions --- .../aiservices/openai/chatcompletion/OpenAIChatCompletion.java | 3 +++ .../aiservices/openai/chatcompletion/OpenAIToolCallConfig.java | 1 + .../semanticfunctions/KernelFunctionFromPrompt.java | 1 + 3 files changed, 5 insertions(+) diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java index 20be752eb..b056bfef1 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java @@ -969,6 +969,7 @@ private static ChatCompletionsOptions getCompletionsOptions( return options; } + @Nullable private static OpenAIToolCallConfig getToolCallConfig( @Nullable InvocationContext invocationContext, @Nullable List functions, @@ -998,6 +999,7 @@ private static OpenAIToolCallConfig getToolCallConfig( } } + @Nullable private static OpenAIToolCallConfig getFunctionChoiceBehaviorConfig( @Nullable FunctionChoiceBehavior functionChoiceBehavior, @Nullable List functions, @@ -1049,6 +1051,7 @@ private static OpenAIToolCallConfig getFunctionChoiceBehaviorConfig( functionChoiceBehavior.getOptions()); } + @Nullable private static OpenAIToolCallConfig getToolCallBehaviorConfig( @Nullable ToolCallBehavior toolCallBehavior, @Nullable List functions, diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java index 4694d2f8b..df7331728 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java @@ -13,6 +13,7 @@ public class OpenAIToolCallConfig { private final List tools; private final ChatCompletionsToolSelection toolChoice; private final boolean autoInvoke; + @Nullable private final FunctionChoiceBehaviorOptions options; /** diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java index 2ea909742..babc1da64 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java @@ -143,6 +143,7 @@ private Flux> invokeInternalAsync( .getServiceSelector() .trySelectAIService( TextAIService.class, + this, args); AIService client = aiServiceSelection != null ? aiServiceSelection.getService() From 66976a9eed9c88eeae5425f83ea317137648b619 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Wed, 30 Apr 2025 13:31:19 -0700 Subject: [PATCH 34/46] Avoid notify thread when auto-invoke is not active --- .../chatcompletion/ChatCompletionAgent.java | 42 +++++++++++++++---- .../agents/CompletionAgent.java | 28 ++++++------- .../semantickernel/agents/Agent.java | 27 ++++++++++++ .../agents/AgentInvokeOptions.java | 4 ++ .../semantickernel/agents/KernelAgent.java | 19 ++++++++- 5 files changed, 98 insertions(+), 22 deletions(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index 7985f5adf..28cb65029 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -6,10 +6,10 @@ import com.microsoft.semantickernel.agents.AgentThread; import com.microsoft.semantickernel.agents.KernelAgent; import com.microsoft.semantickernel.builders.SemanticKernelBuilder; +import com.microsoft.semantickernel.functionchoice.AutoFunctionChoiceBehavior; import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.orchestration.InvocationReturnMode; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; -import com.microsoft.semantickernel.orchestration.ToolCallBehavior; import com.microsoft.semantickernel.semanticfunctions.KernelArguments; import com.microsoft.semantickernel.semanticfunctions.PromptTemplate; import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig; @@ -76,22 +76,20 @@ public Mono>>> invokeAsync( // Invoke the agent with the chat history return internalInvokeAsync( history, + agentThread, options ) - .flatMapMany(Flux::fromIterable) - // notify on the new thread instance - .concatMap(agentMessage -> this.notifyThreadOfNewMessageAsync(agentThread, agentMessage).thenReturn(agentMessage)) - .collectList() .map(chatMessageContents -> chatMessageContents.stream() - .map(message -> new AgentResponseItem>(message, agentThread)) - .collect(Collectors.toList()) + .map(message -> new AgentResponseItem>(message, agentThread)) + .collect(Collectors.toList()) ); }); } private Mono>> internalInvokeAsync( ChatHistory history, + AgentThread thread, @Nullable AgentInvokeOptions options ) { if (options == null) { @@ -144,6 +142,20 @@ private Mono>> internalInvokeAsync( // Add the chat history to the new chat chat.addAll(history); + // Retrieve the chat message contents asynchronously and notify the thread + if (shouldNotifyFunctionCalls(agentInvocationContext)) { + // Notify all messages including function calls + return chatCompletionService.getChatMessageContentsAsync(chat, kernel, agentInvocationContext) + .flatMapMany(Flux::fromIterable) + .concatMap(message -> notifyThreadOfNewMessageAsync(thread, message).thenReturn(message)) + // Filter out function calls and their results + .filter(message -> message.getContent() != null && message.getAuthorRole() != AuthorRole.TOOL) + .collect(Collectors.toList()); + } + + // Return chat completion messages without notifying the thread + // We shouldn't add the function call content to the thread, since + // we don't know if the user will execute the call. They should add it themselves. return chatCompletionService.getChatMessageContentsAsync(chat, kernel, agentInvocationContext); } ); @@ -153,6 +165,22 @@ private Mono>> internalInvokeAsync( } } + boolean shouldNotifyFunctionCalls(InvocationContext invocationContext) { + if (invocationContext == null) { + return false; + } + + if (invocationContext.getFunctionChoiceBehavior() != null && invocationContext.getFunctionChoiceBehavior() instanceof AutoFunctionChoiceBehavior) { + return ((AutoFunctionChoiceBehavior) invocationContext.getFunctionChoiceBehavior()).isAutoInvoke(); + } + + if (invocationContext.getToolCallBehavior() != null) { + return invocationContext.getToolCallBehavior().isAutoInvokeAllowed(); + } + + return false; + } + @Override public Mono notifyThreadOfNewMessageAsync(AgentThread thread, ChatMessageContent message) { diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java index 16941ee41..4c39645cf 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java @@ -6,14 +6,17 @@ import com.azure.core.credential.KeyCredential; import com.microsoft.semantickernel.Kernel; import com.microsoft.semantickernel.agents.AgentInvokeOptions; +import com.microsoft.semantickernel.agents.AgentThread; import com.microsoft.semantickernel.agents.chatcompletion.ChatCompletionAgent; import com.microsoft.semantickernel.agents.chatcompletion.ChatHistoryAgentThread; import com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion; import com.microsoft.semantickernel.contextvariables.ContextVariableTypeConverter; +import com.microsoft.semantickernel.contextvariables.ContextVariableTypes; import com.microsoft.semantickernel.functionchoice.FunctionChoiceBehavior; import com.microsoft.semantickernel.implementation.templateengine.tokenizer.DefaultPromptTemplate; import com.microsoft.semantickernel.orchestration.InvocationContext; import com.microsoft.semantickernel.orchestration.PromptExecutionSettings; +import com.microsoft.semantickernel.orchestration.ToolCallBehavior; import com.microsoft.semantickernel.plugin.KernelPluginFactory; import com.microsoft.semantickernel.samples.plugins.github.GitHubModel; import com.microsoft.semantickernel.samples.plugins.github.GitHubPlugin; @@ -105,7 +108,7 @@ public static void main(String[] args) { ) ).build(); - ChatHistoryAgentThread agentThread = new ChatHistoryAgentThread(); + AgentThread agentThread = new ChatHistoryAgentThread(); Scanner scanner = new Scanner(System.in); while (true) { @@ -118,22 +121,19 @@ public static void main(String[] args) { var message = new ChatMessageContent<>(AuthorRole.USER, input); KernelArguments arguments = KernelArguments.builder() - .withVariable("now", System.currentTimeMillis()) - .build(); + .withVariable("now", System.currentTimeMillis()) + .build(); var response = agent.invokeAsync( - List.of(message), - agentThread, - AgentInvokeOptions.builder() - .withKernel(kernel) - .withKernelArguments(arguments) - .build() - ).block(); - - var lastResponse = response.get(response.size() - 1); + message, + agentThread, + AgentInvokeOptions.builder() + .withKernelArguments(arguments) + .build() + ).block().get(0); - System.out.println("> " + lastResponse.getMessage()); - agentThread = (ChatHistoryAgentThread) lastResponse.getThread(); + System.out.println("> " + response.getMessage()); + agentThread = response.getThread(); } } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java index 3a82550c6..6b8c9ad12 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java @@ -43,6 +43,33 @@ public interface Agent { */ String getDescription(); + /** + * Invokes the agent with the given message. + * + * @param message The message to process + * @return A Mono containing the agent response + */ + Mono>>> invokeAsync(ChatMessageContent message); + + /** + * Invokes the agent with the given message and thread. + * + * @param message The message to process + * @param thread The agent thread to use + * @return A Mono containing the agent response + */ + Mono>>> invokeAsync(ChatMessageContent message, AgentThread thread); + + /** + * Invokes the agent with the given message, thread, and options. + * + * @param message The message to process + * @param thread The agent thread to use + * @param options The options for invoking the agent + * @return A Mono containing the agent response + */ + Mono>>> invokeAsync(ChatMessageContent message, AgentThread thread, AgentInvokeOptions options); + /** * Invoke the agent with the given chat history. * diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java index 3fb4cba18..559a062ce 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java @@ -13,9 +13,13 @@ */ public class AgentInvokeOptions { + @Nullable private final KernelArguments kernelArguments; + @Nullable private final Kernel kernel; + @Nullable private final String additionalInstructions; + @Nullable private final InvocationContext invocationContext; /** diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java index 71e81951d..a3d872297 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java @@ -11,6 +11,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -114,7 +115,6 @@ public PromptTemplate getTemplate() { return template; } - /** * Merges the provided arguments with the current arguments. * Provided arguments will override the current arguments. @@ -167,4 +167,21 @@ protected Mono ensureThreadExistsWithMessagesAsync(Li .then(Mono.just((T) newThread)); }); } + + @Override + public Mono>>> invokeAsync(ChatMessageContent message) { + return invokeAsync(message, null); + } + + @Override + public Mono>>> invokeAsync(ChatMessageContent message, AgentThread thread) { + return invokeAsync(message, thread, AgentInvokeOptions.builder().build()); + } + + @Override + public Mono>>> invokeAsync(ChatMessageContent message, AgentThread thread, AgentInvokeOptions options) { + ArrayList> messages = new ArrayList<>(); + messages.add(message); + return invokeAsync(messages, thread, options); + } } From cbb37c655f34b23a6a92c0718d42739d4c7f01e0 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Wed, 30 Apr 2025 23:51:24 -0700 Subject: [PATCH 35/46] Add @Nullable annotations --- .../chatcompletion/ChatCompletionAgent.java | 2 +- .../semantickernel/agents/Agent.java | 15 +++++++++++---- .../semantickernel/agents/KernelAgent.java | 19 +++++++++++++------ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index 28cb65029..776ed6a54 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -62,7 +62,7 @@ private ChatCompletionAgent( @Override public Mono>>> invokeAsync( List> messages, - AgentThread thread, + @Nullable AgentThread thread, @Nullable AgentInvokeOptions options ) { return ensureThreadExistsWithMessagesAsync(messages, thread, ChatHistoryAgentThread::new) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java index 6b8c9ad12..2277d522d 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java @@ -17,6 +17,8 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import javax.annotation.Nullable; + /** * Interface for a semantic kernel agent. */ @@ -49,7 +51,7 @@ public interface Agent { * @param message The message to process * @return A Mono containing the agent response */ - Mono>>> invokeAsync(ChatMessageContent message); + Mono>>> invokeAsync(@Nullable ChatMessageContent message); /** * Invokes the agent with the given message and thread. @@ -58,7 +60,8 @@ public interface Agent { * @param thread The agent thread to use * @return A Mono containing the agent response */ - Mono>>> invokeAsync(ChatMessageContent message, AgentThread thread); + Mono>>> invokeAsync(@Nullable ChatMessageContent message, + @Nullable AgentThread thread); /** * Invokes the agent with the given message, thread, and options. @@ -68,7 +71,9 @@ public interface Agent { * @param options The options for invoking the agent * @return A Mono containing the agent response */ - Mono>>> invokeAsync(ChatMessageContent message, AgentThread thread, AgentInvokeOptions options); + Mono>>> invokeAsync(@Nullable ChatMessageContent message, + @Nullable AgentThread thread, + @Nullable AgentInvokeOptions options); /** * Invoke the agent with the given chat history. @@ -78,7 +83,9 @@ public interface Agent { * @param options The options for invoking the agent * @return A Mono containing the agent response */ - Mono>>> invokeAsync(List> messages, AgentThread thread, AgentInvokeOptions options); + Mono>>> invokeAsync(List> messages, + @Nullable AgentThread thread, + @Nullable AgentInvokeOptions options); /** * Notifies the agent of a new message. diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java index a3d872297..4d30569fb 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java @@ -11,6 +11,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -169,19 +170,25 @@ protected Mono ensureThreadExistsWithMessagesAsync(Li } @Override - public Mono>>> invokeAsync(ChatMessageContent message) { - return invokeAsync(message, null); + public Mono>>> invokeAsync(@Nullable ChatMessageContent message) { + return invokeAsync(message, null, null); } @Override - public Mono>>> invokeAsync(ChatMessageContent message, AgentThread thread) { - return invokeAsync(message, thread, AgentInvokeOptions.builder().build()); + public Mono>>> invokeAsync(@Nullable ChatMessageContent message, + @Nullable AgentThread thread) { + return invokeAsync(message, thread, null); } @Override - public Mono>>> invokeAsync(ChatMessageContent message, AgentThread thread, AgentInvokeOptions options) { + public Mono>>> invokeAsync( + @Nullable ChatMessageContent message, + @Nullable AgentThread thread, + @Nullable AgentInvokeOptions options) { ArrayList> messages = new ArrayList<>(); - messages.add(message); + if (message != null) { + messages.add(message); + } return invokeAsync(messages, thread, options); } } From b568818bcbd44a617d6046fa8fd229d942b7467c Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 1 May 2025 01:03:14 -0700 Subject: [PATCH 36/46] Add additional constructor for ChatHistoryAgentThread --- .../chatcompletion/ChatHistoryAgentThread.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java index 1a68f8c44..753759c1f 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java @@ -16,12 +16,25 @@ public class ChatHistoryAgentThread extends BaseAgentThread { private ChatHistory chatHistory; + /** + * Constructor for ChatHistoryAgentThread. + * + */ public ChatHistoryAgentThread() { this(UUID.randomUUID().toString(), new ChatHistory()); } /** - * Constructor for com.microsoft.semantickernel.agents.chatcompletion.ChatHistoryAgentThread. + * Constructor for ChatHistoryAgentThread. + * + * @param chatHistory The chat history. + */ + public ChatHistoryAgentThread(@Nullable ChatHistory chatHistory) { + this(UUID.randomUUID().toString(), chatHistory); + } + + /** + * Constructor for ChatHistoryAgentThread. * * @param id The ID of the thread. * @param chatHistory The chat history. @@ -31,6 +44,8 @@ public ChatHistoryAgentThread(String id, @Nullable ChatHistory chatHistory) { this.chatHistory = chatHistory != null ? chatHistory : new ChatHistory(); } + + /** * Get the chat history. * From 81abcbe681ce7400b494ddf0d2a6ae6d9b2437a6 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 1 May 2025 08:26:13 -0700 Subject: [PATCH 37/46] Fix keys of execution settings --- .../semantickernel/semanticfunctions/KernelArguments.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java index e4fb83192..bd519f616 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java @@ -377,7 +377,12 @@ public Builder withExecutionSettings(PromptExecutionSettings executionSetting * @return {$code this} Builder for fluent coding */ public Builder withExecutionSettings(Map executionSettings) { - return withExecutionSettings(new ArrayList<>(executionSettings.values())); + if (executionSettings == null) { + return this; + } + + this.executionSettings.putAll(executionSettings); + return this; } /** From 394367f1cc99248980074a00e3141eb49f035984 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 1 May 2025 10:48:00 -0700 Subject: [PATCH 38/46] Apply format --- .../chatcompletion/ChatCompletionAgent.java | 125 ++++++------- .../ChatHistoryAgentThread.java | 4 +- .../chatcompletion/OpenAIChatCompletion.java | 86 ++++----- .../openai/chatcompletion/OpenAIFunction.java | 14 +- .../chatcompletion/OpenAIToolCallConfig.java | 9 +- .../openai/chatcompletion/JsonSchemaTest.java | 16 +- .../demos/lights/LightModelTypeConverter.java | 8 +- .../samples/demos/lights/LightsPlugin.java | 2 +- .../samples/plugins/github/GitHubModel.java | 69 ++++--- .../samples/plugins/github/GitHubPlugin.java | 170 +++++++----------- .../agents/CompletionAgent.java | 90 +++++----- .../openapi/OpenAPIHttpRequestPlugin.java | 2 +- .../com/microsoft/semantickernel/Kernel.java | 11 +- .../semantickernel/agents/Agent.java | 23 ++- .../agents/AgentInvokeOptions.java | 12 +- .../agents/AgentResponseItem.java | 1 + .../semantickernel/agents/AgentThread.java | 1 + .../agents/BaseAgentThread.java | 2 + .../semantickernel/agents/KernelAgent.java | 69 +++---- .../AutoFunctionChoiceBehavior.java | 5 +- .../FunctionChoiceBehavior.java | 17 +- .../FunctionChoiceBehaviorOptions.java | 1 + .../NoneFunctionChoiceBehavior.java | 4 +- .../RequiredFunctionChoiceBehavior.java | 4 +- .../orchestration/InvocationContext.java | 3 +- .../semanticfunctions/KernelArguments.java | 63 ++++--- .../KernelFunctionFromPrompt.java | 6 +- .../services/BaseAIServiceSelector.java | 11 +- .../services/OrderedAIServiceSelector.java | 76 ++++---- .../chatcompletion/ChatMessageContent.java | 20 +-- 30 files changed, 460 insertions(+), 464 deletions(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index 776ed6a54..140df0f44 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.agents.chatcompletion; import com.microsoft.semantickernel.Kernel; @@ -37,8 +38,7 @@ private ChatCompletionAgent( KernelArguments kernelArguments, InvocationContext context, String instructions, - PromptTemplate template - ) { + PromptTemplate template) { super( id, name, @@ -47,8 +47,7 @@ private ChatCompletionAgent( kernelArguments, context, instructions, - template - ); + template); } /** @@ -61,37 +60,32 @@ private ChatCompletionAgent( */ @Override public Mono>>> invokeAsync( - List> messages, - @Nullable AgentThread thread, - @Nullable AgentInvokeOptions options - ) { + List> messages, + @Nullable AgentThread thread, + @Nullable AgentInvokeOptions options) { return ensureThreadExistsWithMessagesAsync(messages, thread, ChatHistoryAgentThread::new) - .cast(ChatHistoryAgentThread.class) - .flatMap(agentThread -> { - // Extract the chat history from the thread - ChatHistory history = new ChatHistory( - agentThread.getChatHistory().getMessages() - ); - - // Invoke the agent with the chat history - return internalInvokeAsync( - history, - agentThread, - options - ) - .map(chatMessageContents -> - chatMessageContents.stream() - .map(message -> new AgentResponseItem>(message, agentThread)) - .collect(Collectors.toList()) - ); - }); + .cast(ChatHistoryAgentThread.class) + .flatMap(agentThread -> { + // Extract the chat history from the thread + ChatHistory history = new ChatHistory( + agentThread.getChatHistory().getMessages()); + + // Invoke the agent with the chat history + return internalInvokeAsync( + history, + agentThread, + options) + .map(chatMessageContents -> chatMessageContents.stream() + .map(message -> new AgentResponseItem>(message, + agentThread)) + .collect(Collectors.toList())); + }); } private Mono>> internalInvokeAsync( ChatHistory history, AgentThread thread, - @Nullable AgentInvokeOptions options - ) { + @Nullable AgentInvokeOptions options) { if (options == null) { options = new AgentInvokeOptions(); } @@ -99,27 +93,32 @@ private Mono>> internalInvokeAsync( final Kernel kernel = options.getKernel() != null ? options.getKernel() : this.kernel; final KernelArguments arguments = mergeArguments(options.getKernelArguments()); final String additionalInstructions = options.getAdditionalInstructions(); - final InvocationContext invocationContext = options.getInvocationContext() != null ? options.getInvocationContext() : this.invocationContext; + final InvocationContext invocationContext = options.getInvocationContext() != null + ? options.getInvocationContext() + : this.invocationContext; try { - ChatCompletionService chatCompletionService = kernel.getService(ChatCompletionService.class, arguments); + ChatCompletionService chatCompletionService = kernel + .getService(ChatCompletionService.class, arguments); - PromptExecutionSettings executionSettings = invocationContext != null && invocationContext.getPromptExecutionSettings() != null + PromptExecutionSettings executionSettings = invocationContext != null + && invocationContext.getPromptExecutionSettings() != null ? invocationContext.getPromptExecutionSettings() - : kernelArguments.getExecutionSettings().get(chatCompletionService.getServiceId()); + : kernelArguments.getExecutionSettings() + .get(chatCompletionService.getServiceId()); // Build base invocation context InvocationContext.Builder builder = InvocationContext.builder() - .withPromptExecutionSettings(executionSettings) - .withReturnMode(InvocationReturnMode.NEW_MESSAGES_ONLY); + .withPromptExecutionSettings(executionSettings) + .withReturnMode(InvocationReturnMode.NEW_MESSAGES_ONLY); if (invocationContext != null) { builder = builder - .withTelemetry(invocationContext.getTelemetry()) - .withFunctionChoiceBehavior(invocationContext.getFunctionChoiceBehavior()) - .withToolCallBehavior(invocationContext.getToolCallBehavior()) - .withContextVariableConverter(invocationContext.getContextVariableTypes()) - .withKernelHooks(invocationContext.getKernelHooks()); + .withTelemetry(invocationContext.getTelemetry()) + .withFunctionChoiceBehavior(invocationContext.getFunctionChoiceBehavior()) + .withToolCallBehavior(invocationContext.getToolCallBehavior()) + .withContextVariableConverter(invocationContext.getContextVariableTypes()) + .withKernelHooks(invocationContext.getKernelHooks()); } InvocationContext agentInvocationContext = builder.build(); @@ -128,15 +127,13 @@ private Mono>> internalInvokeAsync( instructions -> { // Create a new chat history with the instructions ChatHistory chat = new ChatHistory( - instructions - ); + instructions); // Add agent additional instructions if (additionalInstructions != null) { chat.addMessage(new ChatMessageContent<>( - AuthorRole.SYSTEM, - additionalInstructions - )); + AuthorRole.SYSTEM, + additionalInstructions)); } // Add the chat history to the new chat @@ -145,20 +142,23 @@ private Mono>> internalInvokeAsync( // Retrieve the chat message contents asynchronously and notify the thread if (shouldNotifyFunctionCalls(agentInvocationContext)) { // Notify all messages including function calls - return chatCompletionService.getChatMessageContentsAsync(chat, kernel, agentInvocationContext) + return chatCompletionService + .getChatMessageContentsAsync(chat, kernel, agentInvocationContext) .flatMapMany(Flux::fromIterable) - .concatMap(message -> notifyThreadOfNewMessageAsync(thread, message).thenReturn(message)) + .concatMap(message -> notifyThreadOfNewMessageAsync(thread, message) + .thenReturn(message)) // Filter out function calls and their results - .filter(message -> message.getContent() != null && message.getAuthorRole() != AuthorRole.TOOL) + .filter(message -> message.getContent() != null + && message.getAuthorRole() != AuthorRole.TOOL) .collect(Collectors.toList()); } // Return chat completion messages without notifying the thread // We shouldn't add the function call content to the thread, since // we don't know if the user will execute the call. They should add it themselves. - return chatCompletionService.getChatMessageContentsAsync(chat, kernel, agentInvocationContext); - } - ); + return chatCompletionService.getChatMessageContentsAsync(chat, kernel, + agentInvocationContext); + }); } catch (ServiceNotFoundException e) { return Mono.error(e); @@ -170,8 +170,10 @@ boolean shouldNotifyFunctionCalls(InvocationContext invocationContext) { return false; } - if (invocationContext.getFunctionChoiceBehavior() != null && invocationContext.getFunctionChoiceBehavior() instanceof AutoFunctionChoiceBehavior) { - return ((AutoFunctionChoiceBehavior) invocationContext.getFunctionChoiceBehavior()).isAutoInvoke(); + if (invocationContext.getFunctionChoiceBehavior() != null && invocationContext + .getFunctionChoiceBehavior() instanceof AutoFunctionChoiceBehavior) { + return ((AutoFunctionChoiceBehavior) invocationContext.getFunctionChoiceBehavior()) + .isAutoInvoke(); } if (invocationContext.getToolCallBehavior() != null) { @@ -181,9 +183,9 @@ boolean shouldNotifyFunctionCalls(InvocationContext invocationContext) { return false; } - @Override - public Mono notifyThreadOfNewMessageAsync(AgentThread thread, ChatMessageContent message) { + public Mono notifyThreadOfNewMessageAsync(AgentThread thread, + ChatMessageContent message) { return Mono.defer(() -> { return thread.onNewMessageAsync(message); }); @@ -298,11 +300,10 @@ public ChatCompletionAgent build() { name, description, kernel, - kernelArguments, + kernelArguments, invocationContext, instructions, - template - ); + template); } /** @@ -312,17 +313,17 @@ public ChatCompletionAgent build() { * @param promptTemplateFactory The prompt template factory to use. * @return The ChatCompletionAgent instance. */ - public ChatCompletionAgent build(PromptTemplateConfig promptTemplateConfig, PromptTemplateFactory promptTemplateFactory) { + public ChatCompletionAgent build(PromptTemplateConfig promptTemplateConfig, + PromptTemplateFactory promptTemplateFactory) { return new ChatCompletionAgent( id, name, description, kernel, - kernelArguments, + kernelArguments, invocationContext, promptTemplateConfig.getTemplate(), - promptTemplateFactory.tryCreate(promptTemplateConfig) - ); + promptTemplateFactory.tryCreate(promptTemplateConfig)); } } } diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java index 753759c1f..6b3f62a9b 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatHistoryAgentThread.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.agents.chatcompletion; import com.microsoft.semantickernel.agents.AgentThread; @@ -44,8 +45,6 @@ public ChatHistoryAgentThread(String id, @Nullable ChatHistory chatHistory) { this.chatHistory = chatHistory != null ? chatHistory : new ChatHistory(); } - - /** * Get the chat history. * @@ -91,7 +90,6 @@ public List> getMessages() { return chatHistory.getMessages(); } - public static Builder builder() { return new Builder(); } diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java index b056bfef1..1db5bd388 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIChatCompletion.java @@ -210,8 +210,8 @@ public Flux> getStreamingChatMessageContentsAsync( if (invocationContext != null && invocationContext.getFunctionChoiceBehavior() != null && invocationContext.getFunctionChoiceBehavior() instanceof AutoFunctionChoiceBehavior && - ((AutoFunctionChoiceBehavior) invocationContext.getFunctionChoiceBehavior()).isAutoInvoke() - ) { + ((AutoFunctionChoiceBehavior) invocationContext.getFunctionChoiceBehavior()) + .isAutoInvoke()) { throw new SKException( "FunctionChoiceBehavior auto-invoke is not supported for streaming chat message contents"); } @@ -482,7 +482,8 @@ private Mono internalChatMessageContentsAsync( // Just return the result: // If auto-invoking is not enabled // Or if we are auto-invoking, but we somehow end up with other than 1 choice even though only 1 was requested - if (toolCallConfig == null || !toolCallConfig.isAutoInvoke() || responseMessages.size() != 1) { + if (toolCallConfig == null || !toolCallConfig.isAutoInvoke() + || responseMessages.size() != 1) { List> chatMessageContents = getChatMessageContentsAsync( completions); return Mono.just(messages.addChatMessage(chatMessageContents)); @@ -980,11 +981,11 @@ private static OpenAIToolCallConfig getToolCallConfig( return null; } - if (invocationContext.getFunctionChoiceBehavior() == null && invocationContext.getToolCallBehavior() == null) { + if (invocationContext.getFunctionChoiceBehavior() == null + && invocationContext.getToolCallBehavior() == null) { return null; } - if (invocationContext.getFunctionChoiceBehavior() != null) { return getFunctionChoiceBehaviorConfig( invocationContext.getFunctionChoiceBehavior(), @@ -1015,18 +1016,20 @@ private static OpenAIToolCallConfig getFunctionChoiceBehaviorConfig( ChatCompletionsToolSelection toolChoice; boolean autoInvoke; - if (functionChoiceBehavior instanceof RequiredFunctionChoiceBehavior) { + if (functionChoiceBehavior instanceof RequiredFunctionChoiceBehavior) { // After first request a required function must have been called already if (requestIndex >= 1) { return null; } - toolChoice = new ChatCompletionsToolSelection(ChatCompletionsToolSelectionPreset.REQUIRED); + toolChoice = new ChatCompletionsToolSelection( + ChatCompletionsToolSelectionPreset.REQUIRED); autoInvoke = ((RequiredFunctionChoiceBehavior) functionChoiceBehavior).isAutoInvoke(); } else if (functionChoiceBehavior instanceof AutoFunctionChoiceBehavior) { - toolChoice = new ChatCompletionsToolSelection(ChatCompletionsToolSelectionPreset.AUTO); - autoInvoke = ((AutoFunctionChoiceBehavior) functionChoiceBehavior).isAutoInvoke() && requestIndex < MAXIMUM_INFLIGHT_AUTO_INVOKES; - } else if (functionChoiceBehavior instanceof NoneFunctionChoiceBehavior) { + toolChoice = new ChatCompletionsToolSelection(ChatCompletionsToolSelectionPreset.AUTO); + autoInvoke = ((AutoFunctionChoiceBehavior) functionChoiceBehavior).isAutoInvoke() + && requestIndex < MAXIMUM_INFLIGHT_AUTO_INVOKES; + } else if (functionChoiceBehavior instanceof NoneFunctionChoiceBehavior) { toolChoice = new ChatCompletionsToolSelection(ChatCompletionsToolSelectionPreset.NONE); autoInvoke = false; } else { @@ -1036,13 +1039,14 @@ private static OpenAIToolCallConfig getFunctionChoiceBehaviorConfig( // List of functions advertised to the model List toolDefinitions = functions.stream() - .filter(function -> functionChoiceBehavior.isFunctionAllowed(function.getPluginName(), function.getName())) - .map(OpenAIFunction::getFunctionDefinition) - .map(it -> new ChatCompletionsFunctionToolDefinitionFunction(it.getName()) - .setDescription(it.getDescription()) - .setParameters(it.getParameters())) - .map(ChatCompletionsFunctionToolDefinition::new) - .collect(Collectors.toList()); + .filter(function -> functionChoiceBehavior.isFunctionAllowed(function.getPluginName(), + function.getName())) + .map(OpenAIFunction::getFunctionDefinition) + .map(it -> new ChatCompletionsFunctionToolDefinitionFunction(it.getName()) + .setDescription(it.getDescription()) + .setParameters(it.getParameters())) + .map(ChatCompletionsFunctionToolDefinition::new) + .collect(Collectors.toList()); return new OpenAIToolCallConfig( toolDefinitions, @@ -1100,10 +1104,10 @@ private static OpenAIToolCallConfig getToolCallBehaviorConfig( "{\"type\":\"function\",\"function\":{\"name\":\"%s\"}}", toolChoiceName); toolChoice = new ChatCompletionsToolSelection( - ChatCompletionsNamedToolSelection.fromJson( - DefaultJsonReader.fromString( - json, - new JsonOptions()))); + ChatCompletionsNamedToolSelection.fromJson( + DefaultJsonReader.fromString( + json, + new JsonOptions()))); } catch (JsonProcessingException e) { throw SKException.build("Failed to parse tool choice", e); } catch (IOException e) { @@ -1116,21 +1120,21 @@ private static OpenAIToolCallConfig getToolCallBehaviorConfig( ToolCallBehavior.AllowedKernelFunctions enabledKernelFunctions = (ToolCallBehavior.AllowedKernelFunctions) toolCallBehavior; toolDefinitions = functions.stream() - .filter(function -> { - // check if all kernel functions are enabled - if (enabledKernelFunctions.isAllKernelFunctionsAllowed()) { - return true; - } - // otherwise, check for the specific function - return enabledKernelFunctions.isFunctionAllowed(function.getPluginName(), - function.getName()); - }) - .map(OpenAIFunction::getFunctionDefinition) - .map(it -> new ChatCompletionsFunctionToolDefinitionFunction(it.getName()) - .setDescription(it.getDescription()) - .setParameters(it.getParameters())) - .map(ChatCompletionsFunctionToolDefinition::new) - .collect(Collectors.toList()); + .filter(function -> { + // check if all kernel functions are enabled + if (enabledKernelFunctions.isAllKernelFunctionsAllowed()) { + return true; + } + // otherwise, check for the specific function + return enabledKernelFunctions.isFunctionAllowed(function.getPluginName(), + function.getName()); + }) + .map(OpenAIFunction::getFunctionDefinition) + .map(it -> new ChatCompletionsFunctionToolDefinitionFunction(it.getName()) + .setDescription(it.getDescription()) + .setParameters(it.getParameters())) + .map(ChatCompletionsFunctionToolDefinition::new) + .collect(Collectors.toList()); if (toolDefinitions.isEmpty()) { return null; @@ -1138,10 +1142,12 @@ private static OpenAIToolCallConfig getToolCallBehaviorConfig( } return new OpenAIToolCallConfig( - toolDefinitions, - toolChoice, - toolCallBehavior.isAutoInvokeAllowed() && requestIndex < Math.min(MAXIMUM_INFLIGHT_AUTO_INVOKES, toolCallBehavior.getMaximumAutoInvokeAttempts()), - null); + toolDefinitions, + toolChoice, + toolCallBehavior.isAutoInvokeAllowed() + && requestIndex < Math.min(MAXIMUM_INFLIGHT_AUTO_INVOKES, + toolCallBehavior.getMaximumAutoInvokeAttempts()), + null); } private static boolean hasToolCallBeenExecuted(List chatRequestMessages, diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java index e1f2f2497..cf126d095 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIFunction.java @@ -164,7 +164,7 @@ private static String getSchemaForFunctionParameter(@Nullable InputVariable para entries.add("\"type\":\"" + type + "\""); // Add description if present - String description =null; + String description = null; if (parameter != null && parameter.getDescription() != null && !parameter.getDescription() .isEmpty()) { description = parameter.getDescription(); @@ -173,7 +173,7 @@ private static String getSchemaForFunctionParameter(@Nullable InputVariable para entries.add(String.format("\"description\":\"%s\"", description)); } // If custom type, generate schema - if("object".equalsIgnoreCase(type)) { + if ("object".equalsIgnoreCase(type)) { return getObjectSchema(parameter.getType(), description); } @@ -228,17 +228,17 @@ private static String getJavaTypeToOpenAiFunctionType(String javaType) { } } - private static String getObjectSchema(String type, String description){ - String schema= "{ \"type\" : \"object\" }"; + private static String getObjectSchema(String type, String description) { + String schema = "{ \"type\" : \"object\" }"; try { - Class clazz = Class.forName(type); - schema = ResponseSchemaGenerator.jacksonGenerator().generateSchema(clazz); + Class clazz = Class.forName(type); + schema = ResponseSchemaGenerator.jacksonGenerator().generateSchema(clazz); } catch (ClassNotFoundException | SKException ignored) { } Map properties = BinaryData.fromString(schema).toObject(Map.class); - if(StringUtils.isNotBlank(description)) { + if (StringUtils.isNotBlank(description)) { properties.put("description", description); } return BinaryData.fromObject(properties).toString(); diff --git a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java index df7331728..454ed3ce1 100644 --- a/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java +++ b/aiservices/openai/src/main/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/OpenAIToolCallConfig.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.aiservices.openai.chatcompletion; import com.azure.ai.openai.models.ChatCompletionsToolDefinition; @@ -26,10 +27,10 @@ public class OpenAIToolCallConfig { */ @SuppressFBWarnings("EI_EXPOSE_REP2") public OpenAIToolCallConfig( - List tools, - ChatCompletionsToolSelection toolChoice, - boolean autoInvoke, - @Nullable FunctionChoiceBehaviorOptions options) { + List tools, + ChatCompletionsToolSelection toolChoice, + boolean autoInvoke, + @Nullable FunctionChoiceBehaviorOptions options) { this.tools = tools; this.toolChoice = toolChoice; this.autoInvoke = autoInvoke; diff --git a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java index 68c8dae88..33870fba2 100644 --- a/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java +++ b/aiservices/openai/src/test/java/com/microsoft/semantickernel/aiservices/openai/chatcompletion/JsonSchemaTest.java @@ -47,12 +47,12 @@ public void openAIFunctionTest() { testFunction.getMetadata(), plugin.getName()); - String parameters = "{\"type\":\"object\",\"required\":[\"person\",\"input\"],\"properties\":{\"input\":{\"type\":\"string\",\"description\":\"input string\"},\"person\":{\"type\":\"object\",\"properties\":{\"age\":{\"type\":\"integer\",\"description\":\"The age of the person.\"},\"name\":{\"type\":\"string\",\"description\":\"The name of the person.\"},\"title\":{\"type\":\"string\",\"enum\":[\"MS\",\"MRS\",\"MR\"],\"description\":\"The title of the person.\"}},\"required\":[\"age\",\"name\",\"title\"],\"additionalProperties\":false,\"description\":\"input person\"}}}"; - Assertions.assertEquals(parameters, openAIFunction.getFunctionDefinition().getParameters().toString()); + String parameters = "{\"type\":\"object\",\"required\":[\"person\",\"input\"],\"properties\":{\"input\":{\"type\":\"string\",\"description\":\"input string\"},\"person\":{\"type\":\"object\",\"properties\":{\"age\":{\"type\":\"integer\",\"description\":\"The age of the person.\"},\"name\":{\"type\":\"string\",\"description\":\"The name of the person.\"},\"title\":{\"type\":\"string\",\"enum\":[\"MS\",\"MRS\",\"MR\"],\"description\":\"The title of the person.\"}},\"required\":[\"age\",\"name\",\"title\"],\"additionalProperties\":false,\"description\":\"input person\"}}}"; + Assertions.assertEquals(parameters, + openAIFunction.getFunctionDefinition().getParameters().toString()); } - public static class TestPlugin { @DefineKernelFunction @@ -67,19 +67,16 @@ public Mono asyncTestFunction( return Mono.just(1); } - @DefineKernelFunction(returnType = "int", description = "test function description", - name = "asyncPersonFunction", returnDescription = "test return description") + @DefineKernelFunction(returnType = "int", description = "test function description", name = "asyncPersonFunction", returnDescription = "test return description") public Mono asyncPersonFunction( - @KernelFunctionParameter(name = "person",description = "input person", type = Person.class) Person person, + @KernelFunctionParameter(name = "person", description = "input person", type = Person.class) Person person, @KernelFunctionParameter(name = "input", description = "input string") String input) { return Mono.just(1); } } private static enum Title { - MS, - MRS, - MR + MS, MRS, MR } public static class Person { @@ -90,7 +87,6 @@ public static class Person { @JsonPropertyDescription("The title of the person.") private Title title; - public Person(String name, int age) { this.name = name; this.age = age; diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModelTypeConverter.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModelTypeConverter.java index 250de12e4..2752eb624 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModelTypeConverter.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightModelTypeConverter.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.samples.demos.lights; import com.google.gson.Gson; @@ -10,14 +11,13 @@ public LightModelTypeConverter() { super( LightModel.class, obj -> { - if(obj instanceof String) { - return gson.fromJson((String)obj, LightModel.class); + if (obj instanceof String) { + return gson.fromJson((String) obj, LightModel.class); } else { return gson.fromJson(gson.toJson(obj), LightModel.class); } }, (types, lightModel) -> gson.toJson(lightModel), - json -> gson.fromJson(json, LightModel.class) - ); + json -> gson.fromJson(json, LightModel.class)); } } diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightsPlugin.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightsPlugin.java index fa11addb5..398a8d16d 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightsPlugin.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/demos/lights/LightsPlugin.java @@ -27,7 +27,7 @@ public List getLights() { @DefineKernelFunction(name = "add_light", description = "Adds a new light") public String addLight( @KernelFunctionParameter(name = "newLight", description = "new Light Details", type = LightModel.class) LightModel light) { - if( light != null) { + if (light != null) { System.out.println("Adding light " + light.getName()); lights.add(light); return "Light added"; diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java index 180ec8ed2..0f8065ee1 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.samples.plugins.github; import com.fasterxml.jackson.annotation.JsonCreator; @@ -8,7 +9,7 @@ public abstract class GitHubModel { public final static ObjectMapper objectMapper = new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); @Override public String toString() { @@ -30,12 +31,13 @@ public static class User extends GitHubModel { private String company; @JsonProperty("html_url") private String url; + @JsonCreator public User(@JsonProperty("login") String login, - @JsonProperty("id") long id, - @JsonProperty("name") String name, - @JsonProperty("company") String company, - @JsonProperty("html_url") String url) { + @JsonProperty("id") long id, + @JsonProperty("name") String name, + @JsonProperty("company") String company, + @JsonProperty("html_url") String url) { this.login = login; this.id = id; this.name = name; @@ -46,15 +48,19 @@ public User(@JsonProperty("login") String login, public String getLogin() { return login; } + public long getId() { return id; } + public String getName() { return name; } + public String getCompany() { return company; } + public String getUrl() { return url; } @@ -69,11 +75,12 @@ public static class Repository extends GitHubModel { private String description; @JsonProperty("html_url") private String url; + @JsonCreator public Repository(@JsonProperty("id") long id, - @JsonProperty("full_name") String name, - @JsonProperty("description") String description, - @JsonProperty("html_url") String url) { + @JsonProperty("full_name") String name, + @JsonProperty("description") String description, + @JsonProperty("html_url") String url) { this.id = id; this.name = name; this.description = description; @@ -83,12 +90,15 @@ public Repository(@JsonProperty("id") long id, public long getId() { return id; } + public String getName() { return name; } + public String getDescription() { return description; } + public String getUrl() { return url; } @@ -123,13 +133,13 @@ public static class Issue extends GitHubModel { @JsonCreator public Issue(@JsonProperty("id") long id, - @JsonProperty("number") long number, - @JsonProperty("title") String title, - @JsonProperty("state") String state, - @JsonProperty("html_url") String url, - @JsonProperty("labels") Label[] labels, - @JsonProperty("created_at") String createdAt, - @JsonProperty("closed_at") String closedAt) { + @JsonProperty("number") long number, + @JsonProperty("title") String title, + @JsonProperty("state") String state, + @JsonProperty("html_url") String url, + @JsonProperty("labels") Label[] labels, + @JsonProperty("created_at") String createdAt, + @JsonProperty("closed_at") String closedAt) { this.id = id; this.number = number; this.title = title; @@ -143,24 +153,31 @@ public Issue(@JsonProperty("id") long id, public long getId() { return id; } + public long getNumber() { return number; } + public String getTitle() { return title; } + public String getState() { return state; } + public String getUrl() { return url; } + public Label[] getLabels() { return labels; } + public String getCreatedAt() { return createdAt; } + public String getClosedAt() { return closedAt; } @@ -172,14 +189,14 @@ public static class IssueDetail extends Issue { @JsonCreator public IssueDetail(@JsonProperty("id") long id, - @JsonProperty("number") long number, - @JsonProperty("title") String title, - @JsonProperty("state") String state, - @JsonProperty("html_url") String url, - @JsonProperty("labels") Label[] labels, - @JsonProperty("created_at") String createdAt, - @JsonProperty("closed_at") String closedAt, - @JsonProperty("body") String body) { + @JsonProperty("number") long number, + @JsonProperty("title") String title, + @JsonProperty("state") String state, + @JsonProperty("html_url") String url, + @JsonProperty("labels") Label[] labels, + @JsonProperty("created_at") String createdAt, + @JsonProperty("closed_at") String closedAt, + @JsonProperty("body") String body) { super(id, number, title, state, url, labels, createdAt, closedAt); this.body = body; } @@ -199,8 +216,8 @@ public static class Label extends GitHubModel { @JsonCreator public Label(@JsonProperty("id") long id, - @JsonProperty("name") String name, - @JsonProperty("description") String description) { + @JsonProperty("name") String name, + @JsonProperty("description") String description) { this.id = id; this.name = name; this.description = description; @@ -209,9 +226,11 @@ public Label(@JsonProperty("id") long id, public long getId() { return id; } + public String getName() { return name; } + public String getDescription() { return description; } diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java index d3c59a152..f0bddee10 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.samples.plugins.github; import reactor.core.publisher.Mono; @@ -12,79 +13,47 @@ public class GitHubPlugin { public static final String baseUrl = "https://api.github.com"; private final String token; - public GitHubPlugin(String token) { + public GitHubPlugin(String token) { this.token = token; } - @DefineKernelFunction(name = "get_user_info", description = "Get user information from GitHub", - returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$User") + @DefineKernelFunction(name = "get_user_info", description = "Get user information from GitHub", returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$User") public Mono getUserProfileAsync() { HttpClient client = createClient(); return makeRequestAsync(client, "/user") - .map(json -> { - try { - return GitHubModel.objectMapper.readValue(json, GitHubModel.User.class); - } catch (IOException e) { - throw new IllegalStateException("Failed to deserialize GitHubUser", e); - } - }); + .map(json -> { + try { + return GitHubModel.objectMapper.readValue(json, GitHubModel.User.class); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubUser", e); + } + }); } - @DefineKernelFunction(name = "get_repo_info", description = "Get repository information from GitHub", - returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$Repository") + @DefineKernelFunction(name = "get_repo_info", description = "Get repository information from GitHub", returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$Repository") public Mono getRepositoryAsync( - @KernelFunctionParameter( - name = "organization", - description = "The name of the repository to retrieve information for" - ) String organization, - @KernelFunctionParameter( - name = "repo_name", - description = "The name of the repository to retrieve information for" - ) String repoName - ) { + @KernelFunctionParameter(name = "organization", description = "The name of the repository to retrieve information for") String organization, + @KernelFunctionParameter(name = "repo_name", description = "The name of the repository to retrieve information for") String repoName) { HttpClient client = createClient(); return makeRequestAsync(client, String.format("/repos/%s/%s", organization, repoName)) - .map(json -> { - try { - return GitHubModel.objectMapper.readValue(json, GitHubModel.Repository.class); - } catch (IOException e) { - throw new IllegalStateException("Failed to deserialize GitHubRepository", e); - } - }); + .map(json -> { + try { + return GitHubModel.objectMapper.readValue(json, GitHubModel.Repository.class); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubRepository", e); + } + }); } - @DefineKernelFunction(name = "get_issues", description = "Get issues from GitHub", - returnType = "java.util.List") + @DefineKernelFunction(name = "get_issues", description = "Get issues from GitHub", returnType = "java.util.List") public Mono> getIssuesAsync( - @KernelFunctionParameter( - name = "organization", - description = "The name of the organization to retrieve issues for" - ) String organization, - @KernelFunctionParameter( - name = "repo_name", - description = "The name of the repository to retrieve issues for" - ) String repoName, - @KernelFunctionParameter( - name = "max_results", - description = "The maximum number of issues to retrieve", - required = false, - defaultValue = "10", - type = int.class - ) int maxResults, - @KernelFunctionParameter( - name = "state", - description = "The state of the issues to retrieve", - required = false, - defaultValue = "open" - ) String state, - @KernelFunctionParameter( - name = "assignee", - description = "The assignee of the issues to retrieve", - required = false - ) String assignee - ) { + @KernelFunctionParameter(name = "organization", description = "The name of the organization to retrieve issues for") String organization, + @KernelFunctionParameter(name = "repo_name", description = "The name of the repository to retrieve issues for") String repoName, + @KernelFunctionParameter(name = "max_results", description = "The maximum number of issues to retrieve", required = false, defaultValue = "10", type = int.class) int maxResults, + @KernelFunctionParameter(name = "state", description = "The state of the issues to retrieve", required = false, defaultValue = "open") String state, + @KernelFunctionParameter(name = "assignee", description = "The assignee of the issues to retrieve", required = false) String assignee) { HttpClient client = createClient(); String query = String.format("/repos/%s/%s/issues", organization, repoName); @@ -93,58 +62,49 @@ public Mono> getIssuesAsync( query = buildQueryString(query, "per_page", String.valueOf(maxResults)); return makeRequestAsync(client, query) - .flatMap(json -> { - try { - GitHubModel.Issue[] issues = GitHubModel.objectMapper.readValue(json, GitHubModel.Issue[].class); - return Mono.just(List.of(issues)); - } catch (IOException e) { - throw new IllegalStateException("Failed to deserialize GitHubIssues", e); - } - }); + .flatMap(json -> { + try { + GitHubModel.Issue[] issues = GitHubModel.objectMapper.readValue(json, + GitHubModel.Issue[].class); + return Mono.just(List.of(issues)); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubIssues", e); + } + }); } - @DefineKernelFunction(name = "get_issue_detail_info", description = "Get detail information of a single issue from GitHub", - returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$IssueDetail") + @DefineKernelFunction(name = "get_issue_detail_info", description = "Get detail information of a single issue from GitHub", returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$IssueDetail") public GitHubModel.IssueDetail getIssueDetailAsync( - @KernelFunctionParameter( - name = "organization", - description = "The name of the repository to retrieve information for" - ) String organization, - @KernelFunctionParameter( - name = "repo_name", - description = "The name of the repository to retrieve information for" - ) String repoName, - @KernelFunctionParameter( - name = "issue_number", - description = "The issue number to retrieve information for", - type = int.class - ) int issueNumber - ) { + @KernelFunctionParameter(name = "organization", description = "The name of the repository to retrieve information for") String organization, + @KernelFunctionParameter(name = "repo_name", description = "The name of the repository to retrieve information for") String repoName, + @KernelFunctionParameter(name = "issue_number", description = "The issue number to retrieve information for", type = int.class) int issueNumber) { HttpClient client = createClient(); - return makeRequestAsync(client, String.format("/repos/%s/%s/issues/%d", organization, repoName, issueNumber)) - .map(json -> { - try { - return GitHubModel.objectMapper.readValue(json, GitHubModel.IssueDetail.class); - } catch (IOException e) { - throw new IllegalStateException("Failed to deserialize GitHubIssue", e); - } - }).block(); + return makeRequestAsync(client, + String.format("/repos/%s/%s/issues/%d", organization, repoName, issueNumber)) + .map(json -> { + try { + return GitHubModel.objectMapper.readValue(json, GitHubModel.IssueDetail.class); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubIssue", e); + } + }).block(); } private HttpClient createClient() { return HttpClient.create() - .baseUrl(baseUrl) - .headers(headers -> { - headers.add("User-Agent", "request"); - headers.add("Accept", "application/vnd.github+json"); - headers.add("Authorization", "Bearer " + token); - headers.add("X-GitHub-Api-Version", "2022-11-28"); - }); + .baseUrl(baseUrl) + .headers(headers -> { + headers.add("User-Agent", "request"); + headers.add("Accept", "application/vnd.github+json"); + headers.add("Authorization", "Bearer " + token); + headers.add("X-GitHub-Api-Version", "2022-11-28"); + }); } private static String buildQueryString(String path, String param, String value) { - if (value == null || value.isEmpty() || value.equals(KernelFunctionParameter.NO_DEFAULT_VALUE)) { + if (value == null || value.isEmpty() + || value.equals(KernelFunctionParameter.NO_DEFAULT_VALUE)) { return path; } @@ -153,13 +113,13 @@ private static String buildQueryString(String path, String param, String value) private Mono makeRequestAsync(HttpClient client, String path) { return client - .get() - .uri(path) - .responseSingle((res, content) -> { - if (res.status().code() != 200) { - return Mono.error(new IllegalStateException("Request failed: " + res.status())); - } - return content.asString(); - }); + .get() + .uri(path) + .responseSingle((res, content) -> { + if (res.status().code() != 200) { + return Mono.error(new IllegalStateException("Request failed: " + res.status())); + } + return content.asString(); + }); } } diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java index 4c39645cf..336406a33 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/src/main/java/com/microsoft/semantickernel/samples/syntaxexamples/agents/CompletionAgent.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.samples.syntaxexamples.agents; import com.azure.ai.openai.OpenAIAsyncClient; @@ -36,9 +37,10 @@ public class CompletionAgent { // Only required if AZURE_CLIENT_KEY is set private static final String CLIENT_ENDPOINT = System.getenv("CLIENT_ENDPOINT"); private static final String MODEL_ID = System.getenv() - .getOrDefault("MODEL_ID", "gpt-4o"); + .getOrDefault("MODEL_ID", "gpt-4o"); private static final String GITHUB_PAT = System.getenv("GITHUB_PAT"); + public static void main(String[] args) { System.out.println("======== ChatCompletion Agent ========"); @@ -46,67 +48,63 @@ public static void main(String[] args) { if (AZURE_CLIENT_KEY != null) { client = new OpenAIClientBuilder() - .credential(new AzureKeyCredential(AZURE_CLIENT_KEY)) - .endpoint(CLIENT_ENDPOINT) - .buildAsyncClient(); + .credential(new AzureKeyCredential(AZURE_CLIENT_KEY)) + .endpoint(CLIENT_ENDPOINT) + .buildAsyncClient(); } else { client = new OpenAIClientBuilder() - .credential(new KeyCredential(CLIENT_KEY)) - .buildAsyncClient(); + .credential(new KeyCredential(CLIENT_KEY)) + .buildAsyncClient(); } System.out.println("------------------------"); ChatCompletionService chatCompletion = OpenAIChatCompletion.builder() - .withModelId(MODEL_ID) - .withOpenAIAsyncClient(client) - .build(); + .withModelId(MODEL_ID) + .withOpenAIAsyncClient(client) + .build(); Kernel kernel = Kernel.builder() - .withAIService(ChatCompletionService.class, chatCompletion) - .withPlugin(KernelPluginFactory.createFromObject(new GitHubPlugin(GITHUB_PAT), - "GitHubPlugin")) - .build(); + .withAIService(ChatCompletionService.class, chatCompletion) + .withPlugin(KernelPluginFactory.createFromObject(new GitHubPlugin(GITHUB_PAT), + "GitHubPlugin")) + .build(); InvocationContext invocationContext = InvocationContext.builder() - .withFunctionChoiceBehavior(FunctionChoiceBehavior.auto(true)) - .withContextVariableConverter(new ContextVariableTypeConverter<>( - GitHubModel.Issue.class, - o -> (GitHubModel.Issue) o, - o -> o.toString(), - s -> null - )) - .build(); + .withFunctionChoiceBehavior(FunctionChoiceBehavior.auto(true)) + .withContextVariableConverter(new ContextVariableTypeConverter<>( + GitHubModel.Issue.class, + o -> (GitHubModel.Issue) o, + o -> o.toString(), + s -> null)) + .build(); ChatCompletionAgent agent = ChatCompletionAgent.builder() - .withKernel(kernel) - .withKernelArguments( - KernelArguments.builder() - .withVariable("repository", "microsoft/semantic-kernel-java") - .withExecutionSettings(PromptExecutionSettings.builder() - .build()) - .build() - ) - .withInvocationContext(invocationContext) - .withTemplate( - DefaultPromptTemplate.build( - PromptTemplateConfig.builder() - .withTemplate( - """ + .withKernel(kernel) + .withKernelArguments( + KernelArguments.builder() + .withVariable("repository", "microsoft/semantic-kernel-java") + .withExecutionSettings(PromptExecutionSettings.builder() + .build()) + .build()) + .withInvocationContext(invocationContext) + .withTemplate( + DefaultPromptTemplate.build( + PromptTemplateConfig.builder() + .withTemplate( + """ You are an agent designed to query and retrieve information from a single GitHub repository in a read-only manner. You are also able to access the profile of the active user. - + Use the current date and time to provide up-to-date details or time-sensitive responses. - + The repository you are querying is a public repository with the following name: {{$repository}} - + The current date and time is: {{$now}}. - """ - ) - .build() - ) - ).build(); + """) + .build())) + .build(); AgentThread agentThread = new ChatHistoryAgentThread(); Scanner scanner = new Scanner(System.in); @@ -128,9 +126,9 @@ public static void main(String[] args) { message, agentThread, AgentInvokeOptions.builder() - .withKernelArguments(arguments) - .build() - ).block().get(0); + .withKernelArguments(arguments) + .build()) + .block().get(0); System.out.println("> " + response.getMessage()); agentThread = response.getThread(); diff --git a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/OpenAPIHttpRequestPlugin.java b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/OpenAPIHttpRequestPlugin.java index 58b3e5250..ebdc84495 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/OpenAPIHttpRequestPlugin.java +++ b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/src/main/java/com/microsoft/semantickernel/samples/openapi/OpenAPIHttpRequestPlugin.java @@ -142,7 +142,7 @@ private String buildQueryPath(KernelArguments arguments) { } private static String getRenderedParameter( - KernelArguments arguments, String name) { + KernelArguments arguments, String name) { ContextVariable value = arguments.get(name); if (value == null) { diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java index d8059ef78..5e6cc2fdf 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/Kernel.java @@ -192,7 +192,7 @@ public FunctionInvocation invokePromptAsync(@Nonnull String prompt, */ public FunctionInvocation invokePromptAsync(@Nonnull String prompt, - @Nonnull KernelArguments arguments, @Nonnull InvocationContext invocationContext) { + @Nonnull KernelArguments arguments, @Nonnull InvocationContext invocationContext) { KernelFunction function = KernelFunction.createFromPrompt(prompt).build(); @@ -327,11 +327,12 @@ public T getService(Class clazz) throws ServiceNotFound * @throws ServiceNotFoundException if the service is not found. * @see com.microsoft.semantickernel.services.AIServiceSelector#trySelectAIService(Class, KernelArguments) */ - public T getService(Class clazz, KernelArguments args) throws ServiceNotFoundException { + public T getService(Class clazz, KernelArguments args) + throws ServiceNotFoundException { AIServiceSelection selector = serviceSelector - .trySelectAIService( - clazz, - args); + .trySelectAIService( + clazz, + args); if (selector == null) { throw new ServiceNotFoundException("Unable to find service of type " + clazz.getName()); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java index 2277d522d..f69b2152d 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/Agent.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.agents; import java.util.HashMap; @@ -51,7 +52,8 @@ public interface Agent { * @param message The message to process * @return A Mono containing the agent response */ - Mono>>> invokeAsync(@Nullable ChatMessageContent message); + Mono>>> invokeAsync( + @Nullable ChatMessageContent message); /** * Invokes the agent with the given message and thread. @@ -60,8 +62,9 @@ public interface Agent { * @param thread The agent thread to use * @return A Mono containing the agent response */ - Mono>>> invokeAsync(@Nullable ChatMessageContent message, - @Nullable AgentThread thread); + Mono>>> invokeAsync( + @Nullable ChatMessageContent message, + @Nullable AgentThread thread); /** * Invokes the agent with the given message, thread, and options. @@ -71,9 +74,10 @@ Mono>>> invokeAsync(@Nullable ChatM * @param options The options for invoking the agent * @return A Mono containing the agent response */ - Mono>>> invokeAsync(@Nullable ChatMessageContent message, - @Nullable AgentThread thread, - @Nullable AgentInvokeOptions options); + Mono>>> invokeAsync( + @Nullable ChatMessageContent message, + @Nullable AgentThread thread, + @Nullable AgentInvokeOptions options); /** * Invoke the agent with the given chat history. @@ -83,9 +87,10 @@ Mono>>> invokeAsync(@Nullable ChatM * @param options The options for invoking the agent * @return A Mono containing the agent response */ - Mono>>> invokeAsync(List> messages, - @Nullable AgentThread thread, - @Nullable AgentInvokeOptions options); + Mono>>> invokeAsync( + List> messages, + @Nullable AgentThread thread, + @Nullable AgentInvokeOptions options); /** * Notifies the agent of a new message. diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java index 559a062ce..6b6d57ed3 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentInvokeOptions.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.agents; import com.microsoft.semantickernel.Kernel; @@ -38,9 +39,9 @@ public AgentInvokeOptions() { * @param invocationContext The invocation context. */ public AgentInvokeOptions(@Nullable KernelArguments kernelArguments, - @Nullable Kernel kernel, - @Nullable String additionalInstructions, - @Nullable InvocationContext invocationContext) { + @Nullable Kernel kernel, + @Nullable String additionalInstructions, + @Nullable InvocationContext invocationContext) { this.kernelArguments = kernelArguments != null ? kernelArguments.copy() : null; this.kernel = kernel; this.additionalInstructions = additionalInstructions; @@ -84,8 +85,6 @@ public InvocationContext getInvocationContext() { return invocationContext; } - - /** * Builder for AgentInvokeOptions. */ @@ -156,8 +155,7 @@ public AgentInvokeOptions build() { kernelArguments, kernel, additionalInstructions, - invocationContext - ); + invocationContext); } } } \ No newline at end of file diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java index f585bfeab..0b4550986 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentResponseItem.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.agents; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java index d369d999d..94538f41a 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/AgentThread.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.agents; import com.microsoft.semantickernel.services.chatcompletion.ChatMessageContent; diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/BaseAgentThread.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/BaseAgentThread.java index b7c97eea9..c66fe9b90 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/BaseAgentThread.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/BaseAgentThread.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.agents; public abstract class BaseAgentThread implements AgentThread { @@ -16,6 +17,7 @@ public BaseAgentThread(String id) { public String getId() { return id; } + @Override public boolean isDeleted() { return isDeleted; diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java index 4d30569fb..8403093eb 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/agents/KernelAgent.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.agents; import com.microsoft.semantickernel.Kernel; @@ -31,23 +32,24 @@ public abstract class KernelAgent implements Agent { protected final PromptTemplate template; protected KernelAgent( - String id, - String name, - String description, - Kernel kernel, - KernelArguments kernelArguments, - InvocationContext invocationContext, - String instructions, - PromptTemplate template - ) { + String id, + String name, + String description, + Kernel kernel, + KernelArguments kernelArguments, + InvocationContext invocationContext, + String instructions, + PromptTemplate template) { this.id = id != null ? id : UUID.randomUUID().toString(); this.name = name; this.description = description; this.kernel = kernel; this.kernelArguments = kernelArguments != null - ? kernelArguments.copy() : KernelArguments.builder().build(); + ? kernelArguments.copy() + : KernelArguments.builder().build(); this.invocationContext = invocationContext != null - ? invocationContext : InvocationContext.builder().build(); + ? invocationContext + : InvocationContext.builder().build(); this.instructions = instructions; this.template = template; } @@ -127,14 +129,15 @@ protected KernelArguments mergeArguments(KernelArguments arguments) { return kernelArguments; } - Map executionSettings = new HashMap<>(kernelArguments.getExecutionSettings()); + Map executionSettings = new HashMap<>( + kernelArguments.getExecutionSettings()); executionSettings.putAll(arguments.getExecutionSettings()); return KernelArguments.builder() - .withVariables(kernelArguments) - .withVariables(arguments) - .withExecutionSettings(executionSettings) - .build(); + .withVariables(kernelArguments) + .withVariables(arguments) + .withExecutionSettings(executionSettings) + .build(); } /** @@ -145,7 +148,8 @@ protected KernelArguments mergeArguments(KernelArguments arguments) { * @param context The context to use for formatting. * @return A Mono that resolves to the formatted instructions. */ - protected Mono renderInstructionsAsync(Kernel kernel, KernelArguments arguments, InvocationContext context) { + protected Mono renderInstructionsAsync(Kernel kernel, KernelArguments arguments, + InvocationContext context) { if (template != null) { return template.renderAsync(kernel, arguments, context); } else { @@ -153,38 +157,41 @@ protected Mono renderInstructionsAsync(Kernel kernel, KernelArguments ar } } - protected Mono ensureThreadExistsWithMessagesAsync(List> messages, AgentThread thread, Supplier threadSupplier) { + protected Mono ensureThreadExistsWithMessagesAsync( + List> messages, AgentThread thread, Supplier threadSupplier) { return Mono.defer(() -> { // Check if the thread already exists // If it does, we can work with a copy of it AgentThread newThread = thread == null ? threadSupplier.get() : thread.copy(); - return newThread.createAsync() - .thenMany(Flux.fromIterable(messages)) - .concatMap(message -> { - return notifyThreadOfNewMessageAsync(newThread, message) - .then(Mono.just(message)); - }) - .then(Mono.just((T) newThread)); + return newThread.createAsync() + .thenMany(Flux.fromIterable(messages)) + .concatMap(message -> { + return notifyThreadOfNewMessageAsync(newThread, message) + .then(Mono.just(message)); + }) + .then(Mono.just((T) newThread)); }); } @Override - public Mono>>> invokeAsync(@Nullable ChatMessageContent message) { + public Mono>>> invokeAsync( + @Nullable ChatMessageContent message) { return invokeAsync(message, null, null); } @Override - public Mono>>> invokeAsync(@Nullable ChatMessageContent message, - @Nullable AgentThread thread) { + public Mono>>> invokeAsync( + @Nullable ChatMessageContent message, + @Nullable AgentThread thread) { return invokeAsync(message, thread, null); } @Override public Mono>>> invokeAsync( - @Nullable ChatMessageContent message, - @Nullable AgentThread thread, - @Nullable AgentInvokeOptions options) { + @Nullable ChatMessageContent message, + @Nullable AgentThread thread, + @Nullable AgentInvokeOptions options) { ArrayList> messages = new ArrayList<>(); if (message != null) { messages.add(message); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/AutoFunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/AutoFunctionChoiceBehavior.java index 3e3878b76..b4993f44c 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/AutoFunctionChoiceBehavior.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/AutoFunctionChoiceBehavior.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.functionchoice; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; @@ -22,8 +23,8 @@ public class AutoFunctionChoiceBehavior extends FunctionChoiceBehavior { * @param options Options for the function choice behavior. */ public AutoFunctionChoiceBehavior(boolean autoInvoke, - @Nullable List> functions, - @Nullable FunctionChoiceBehaviorOptions options) { + @Nullable List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { super(functions, options); this.autoInvoke = autoInvoke; } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java index bfa397856..cbf64bde0 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java @@ -20,14 +20,14 @@ public abstract class FunctionChoiceBehavior { protected final FunctionChoiceBehaviorOptions options; protected FunctionChoiceBehavior(@Nullable List> functions, - @Nullable FunctionChoiceBehaviorOptions options) { + @Nullable FunctionChoiceBehaviorOptions options) { this.functions = functions != null ? Collections.unmodifiableList(functions) : null; this.fullFunctionNames = new HashSet<>(); if (functions != null) { functions.stream().filter(Objects::nonNull).forEach( - f -> this.fullFunctionNames - .add(formFullFunctionName(f.getPluginName(), f.getName()))); + f -> this.fullFunctionNames + .add(formFullFunctionName(f.getPluginName(), f.getName()))); } if (options != null) { @@ -79,8 +79,8 @@ public static FunctionChoiceBehavior auto(boolean autoInvoke) { * @return A new FunctionChoiceBehavior instance with all kernel functions allowed. */ public static FunctionChoiceBehavior auto(boolean autoInvoke, - List> functions, - @Nullable FunctionChoiceBehaviorOptions options) { + List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { return new AutoFunctionChoiceBehavior(autoInvoke, functions, options); } @@ -96,8 +96,8 @@ public static FunctionChoiceBehavior auto(boolean autoInvoke, * @return A new FunctionChoiceBehavior instance with the required function. */ public static FunctionChoiceBehavior required(boolean autoInvoke, - List> functions, - @Nullable FunctionChoiceBehaviorOptions options) { + List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { return new RequiredFunctionChoiceBehavior(autoInvoke, functions, options); } @@ -110,11 +110,10 @@ public static FunctionChoiceBehavior required(boolean autoInvoke, * If empty, no functions are provided to the model, which is equivalent to disabling function calling. */ public static FunctionChoiceBehavior none(List> functions, - @Nullable FunctionChoiceBehaviorOptions options) { + @Nullable FunctionChoiceBehaviorOptions options) { return new NoneFunctionChoiceBehavior(functions, options); } - /** * The separator between the plugin name and the function name. */ diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehaviorOptions.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehaviorOptions.java index bbde7c578..ffb17c780 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehaviorOptions.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehaviorOptions.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.functionchoice; import com.microsoft.semantickernel.builders.SemanticKernelBuilder; diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java index 0ee7f1a01..e5bef9f48 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.functionchoice; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; @@ -9,7 +10,8 @@ public class NoneFunctionChoiceBehavior extends FunctionChoiceBehavior { /** * Create a new instance of NoneFunctionChoiceBehavior. */ - public NoneFunctionChoiceBehavior(List> functions, FunctionChoiceBehaviorOptions options) { + public NoneFunctionChoiceBehavior(List> functions, + FunctionChoiceBehaviorOptions options) { super(functions, options); } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java index 57312b0fb..01710cca3 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java @@ -1,3 +1,4 @@ +// Copyright (c) Microsoft. All rights reserved. package com.microsoft.semantickernel.functionchoice; import com.microsoft.semantickernel.semanticfunctions.KernelFunction; @@ -13,7 +14,8 @@ public class RequiredFunctionChoiceBehavior extends AutoFunctionChoiceBehavior { * @param functions A set of functions to advertise to the model. * @param options Options for the function choice behavior. */ - public RequiredFunctionChoiceBehavior(boolean autoInvoke, List> functions, FunctionChoiceBehaviorOptions options) { + public RequiredFunctionChoiceBehavior(boolean autoInvoke, List> functions, + FunctionChoiceBehaviorOptions options) { super(autoInvoke, functions, options); } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java index 48c10949c..6a8547c43 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/orchestration/InvocationContext.java @@ -323,7 +323,8 @@ public InvocationContext build() { if (telemetry == null) { telemetry = new SemanticKernelTelemetry(); } - return new InvocationContext(hooks, promptExecutionSettings, toolCallBehavior, functionChoiceBehavior, + return new InvocationContext(hooks, promptExecutionSettings, toolCallBehavior, + functionChoiceBehavior, contextVariableTypes, invocationReturnMode, telemetry); } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java index bd519f616..bf9e65658 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelArguments.java @@ -42,8 +42,8 @@ public class KernelArguments implements Map> { * @param variables The variables to use for the function invocation. */ protected KernelArguments( - @Nullable Map> variables, - @Nullable Map executionSettings) { + @Nullable Map> variables, + @Nullable Map executionSettings) { if (variables == null) { this.variables = new CaseInsensitiveMap<>(); } else { @@ -112,14 +112,14 @@ public ContextVariable getInput() { */ public String prettyPrint() { return variables.entrySet().stream() - .reduce( - "", - (str, entry) -> str - + System.lineSeparator() - + entry.getKey() - + ": " - + entry.getValue().toPromptString(ContextVariableTypes.getGlobalTypes()), - (a, b) -> a + b); + .reduce( + "", + (str, entry) -> str + + System.lineSeparator() + + entry.getKey() + + ": " + + entry.getValue().toPromptString(ContextVariableTypes.getGlobalTypes()), + (a, b) -> a + b); } /** @@ -149,9 +149,9 @@ ContextVariable get(String key, Class clazz) { } throw new SKException( - String.format( - "Variable %s is of type %s, but requested type is %s", - key, value.getType().getClazz(), clazz)); + String.format( + "Variable %s is of type %s, but requested type is %s", + key, value.getType().getClazz(), clazz)); } /** @@ -243,7 +243,6 @@ public static Builder builder() { return new Builder<>(KernelArguments::new); } - /** * Builder for ContextVariables */ @@ -253,7 +252,6 @@ public static class Builder implements SemanticKernel private final Map> variables; private final Map executionSettings; - protected Builder(Function constructor) { this.constructor = constructor; this.variables = new HashMap<>(); @@ -293,10 +291,10 @@ public Builder withInput(Object content) { */ public Builder withInput(T content, ContextVariableTypeConverter typeConverter) { return withInput(new ContextVariable<>( - new ContextVariableType<>( - typeConverter, - typeConverter.getType()), - content)); + new ContextVariableType<>( + typeConverter, + typeConverter.getType()), + content)); } /** @@ -352,12 +350,12 @@ public Builder withVariable(String key, Object value) { * @throws SKException if the value cannot be converted to a ContextVariable */ public Builder withVariable(String key, T value, - ContextVariableTypeConverter typeConverter) { + ContextVariableTypeConverter typeConverter) { return withVariable(key, new ContextVariable<>( - new ContextVariableType<>( - typeConverter, - typeConverter.getType()), - value)); + new ContextVariableType<>( + typeConverter, + typeConverter.getType()), + value)); } /** @@ -376,7 +374,8 @@ public Builder withExecutionSettings(PromptExecutionSettings executionSetting * @param executionSettings Execution settings * @return {$code this} Builder for fluent coding */ - public Builder withExecutionSettings(Map executionSettings) { + public Builder withExecutionSettings( + Map executionSettings) { if (executionSettings == null) { return this; } @@ -402,17 +401,15 @@ public Builder withExecutionSettings(List executionS if (this.executionSettings.containsKey(serviceId)) { if (serviceId.equals(PromptExecutionSettings.DEFAULT_SERVICE_ID)) { throw new SKException( - String.format( - "Multiple prompt execution settings with the default service id '%s' or no service id have been provided. Specify a single default prompt execution settings and provide a unique service id for all other instances.", - PromptExecutionSettings.DEFAULT_SERVICE_ID) - ); + String.format( + "Multiple prompt execution settings with the default service id '%s' or no service id have been provided. Specify a single default prompt execution settings and provide a unique service id for all other instances.", + PromptExecutionSettings.DEFAULT_SERVICE_ID)); } throw new SKException( - String.format( - "Multiple prompt execution settings with the service id '%s' have been provided. Specify a unique service id for all instances.", - serviceId) - ); + String.format( + "Multiple prompt execution settings with the service id '%s' have been provided. Specify a unique service id for all instances.", + serviceId)); } this.executionSettings.put(serviceId, settings); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java index babc1da64..642b5addc 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/semanticfunctions/KernelFunctionFromPrompt.java @@ -135,9 +135,9 @@ private Flux> invokeInternalAsync( .executeHooks(new FunctionInvokingEvent(this, args)); args = KernelArguments.builder() - .withVariables(invokingEvent.getArguments()) - .withExecutionSettings(this.getExecutionSettings()) - .build(); + .withVariables(invokingEvent.getArguments()) + .withExecutionSettings(this.getExecutionSettings()) + .build(); AIServiceSelection aiServiceSelection = kernel .getServiceSelector() diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java index 03ecdd781..b022bf358 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/BaseAIServiceSelector.java @@ -38,8 +38,8 @@ public AIServiceSelection trySelectAIService( @Override @Nullable public AIServiceSelection trySelectAIService( - Class serviceType, - @Nullable KernelArguments arguments) { + Class serviceType, + @Nullable KernelArguments arguments) { return trySelectAIService(serviceType, arguments, services); } @@ -64,7 +64,6 @@ protected abstract AIServiceSelection trySelectAIServic @Nullable KernelArguments arguments, Map, AIService> services); - /** * Resolves an {@link AIService} from the {@code services} argument using the specified * {@code function} and {@code arguments} for selection. @@ -79,9 +78,9 @@ protected abstract AIServiceSelection trySelectAIServic */ @Nullable protected AIServiceSelection trySelectAIService( - Class serviceType, - @Nullable KernelArguments arguments, - Map, AIService> services) { + Class serviceType, + @Nullable KernelArguments arguments, + Map, AIService> services) { return trySelectAIService(serviceType, null, arguments, services); } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java index 6b04fe2b4..30828233d 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/OrderedAIServiceSelector.java @@ -66,16 +66,16 @@ public AIServiceSelection trySelectAIService( Map, AIService> services) { if (function == null) { - return selectAIService(serviceType, arguments != null ? arguments.getExecutionSettings() : null); + return selectAIService(serviceType, + arguments != null ? arguments.getExecutionSettings() : null); } return selectAIService(serviceType, function.getExecutionSettings()); } - private AIServiceSelection selectAIService( - Class serviceType, - @Nullable Map executionSettings) { + Class serviceType, + @Nullable Map executionSettings) { if (executionSettings == null || executionSettings.isEmpty()) { AIService service = getAnyService(serviceType); @@ -84,50 +84,50 @@ private AIServiceSelection selectAIService( } } else { AIServiceSelection selection = executionSettings - .entrySet() - .stream() - .map(keyValue -> { - - PromptExecutionSettings settings = keyValue.getValue(); - String serviceId = keyValue.getKey(); - - if (!Verify.isNullOrEmpty(serviceId)) { - AIService service = getService(serviceId); - if (service != null) { - return castServiceSelection( - new AIServiceSelection<>(service, settings)); - } + .entrySet() + .stream() + .map(keyValue -> { + + PromptExecutionSettings settings = keyValue.getValue(); + String serviceId = keyValue.getKey(); + + if (!Verify.isNullOrEmpty(serviceId)) { + AIService service = getService(serviceId); + if (service != null) { + return castServiceSelection( + new AIServiceSelection<>(service, settings)); } + } - return null; - }) - .filter(Objects::nonNull) - .findFirst() - .orElseGet(() -> null); + return null; + }) + .filter(Objects::nonNull) + .findFirst() + .orElseGet(() -> null); if (selection != null) { return castServiceSelection(selection); } selection = executionSettings - .entrySet() - .stream() - .map(keyValue -> { - PromptExecutionSettings settings = keyValue.getValue(); - - if (!Verify.isNullOrEmpty(settings.getModelId())) { - AIService service = getServiceByModelId(settings.getModelId()); - if (service != null) { - return castServiceSelection( - new AIServiceSelection<>(service, settings)); - } + .entrySet() + .stream() + .map(keyValue -> { + PromptExecutionSettings settings = keyValue.getValue(); + + if (!Verify.isNullOrEmpty(settings.getModelId())) { + AIService service = getServiceByModelId(settings.getModelId()); + if (service != null) { + return castServiceSelection( + new AIServiceSelection<>(service, settings)); } + } - return null; - }) - .filter(Objects::nonNull) - .findFirst() - .orElseGet(() -> null); + return null; + }) + .filter(Objects::nonNull) + .findFirst() + .orElseGet(() -> null); if (selection != null) { return castServiceSelection(selection); diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java index 0408860e9..e06472d12 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/services/chatcompletion/ChatMessageContent.java @@ -60,17 +60,17 @@ public ChatMessageContent( * @param content the content */ public ChatMessageContent( - AuthorRole authorRole, - String authorName, - String content) { + AuthorRole authorRole, + String authorName, + String content) { this( - authorRole, - authorName, - content, - null, - null, - null, - null); + authorRole, + authorName, + content, + null, + null, + null, + null); } /** From c535e613f63e1af8855f81bbad6e8f8fd53d727e Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 1 May 2025 11:02:13 -0700 Subject: [PATCH 39/46] Small fix --- .../agents/chatcompletion/ChatCompletionAgent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java index 140df0f44..b5294fe6b 100644 --- a/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java +++ b/agents/semantickernel-agents-core/src/main/java/com/microsoft/semantickernel/agents/chatcompletion/ChatCompletionAgent.java @@ -104,7 +104,7 @@ private Mono>> internalInvokeAsync( PromptExecutionSettings executionSettings = invocationContext != null && invocationContext.getPromptExecutionSettings() != null ? invocationContext.getPromptExecutionSettings() - : kernelArguments.getExecutionSettings() + : arguments.getExecutionSettings() .get(chatCompletionService.getServiceId()); // Build base invocation context From 730af6c571f7a53f0b63f0808149e77fb12e27ef Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Thu, 1 May 2025 12:55:50 -0700 Subject: [PATCH 40/46] Add Github plugin to learn resources --- .../samples/plugins/github/GitHubModel.java | 238 ++++++++++++++++++ .../samples/plugins/github/GitHubPlugin.java | 125 +++++++++ 2 files changed, 363 insertions(+) create mode 100644 samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java create mode 100644 samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java diff --git a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java new file mode 100644 index 000000000..0f8065ee1 --- /dev/null +++ b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubModel.java @@ -0,0 +1,238 @@ +// Copyright (c) Microsoft. All rights reserved. +package com.microsoft.semantickernel.samples.plugins.github; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +public abstract class GitHubModel { + public final static ObjectMapper objectMapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + @Override + public String toString() { + try { + return objectMapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + public static class User extends GitHubModel { + @JsonProperty("login") + private String login; + @JsonProperty("id") + private long id; + @JsonProperty("name") + private String name; + @JsonProperty("company") + private String company; + @JsonProperty("html_url") + private String url; + + @JsonCreator + public User(@JsonProperty("login") String login, + @JsonProperty("id") long id, + @JsonProperty("name") String name, + @JsonProperty("company") String company, + @JsonProperty("html_url") String url) { + this.login = login; + this.id = id; + this.name = name; + this.company = company; + this.url = url; + } + + public String getLogin() { + return login; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getCompany() { + return company; + } + + public String getUrl() { + return url; + } + } + + public static class Repository extends GitHubModel { + @JsonProperty("id") + private long id; + @JsonProperty("full_name") + private String name; + @JsonProperty("description") + private String description; + @JsonProperty("html_url") + private String url; + + @JsonCreator + public Repository(@JsonProperty("id") long id, + @JsonProperty("full_name") String name, + @JsonProperty("description") String description, + @JsonProperty("html_url") String url) { + this.id = id; + this.name = name; + this.description = description; + this.url = url; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getUrl() { + return url; + } + + @Override + public String toString() { + try { + return objectMapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + } + + public static class Issue extends GitHubModel { + @JsonProperty("id") + private long id; + @JsonProperty("number") + private long number; + @JsonProperty("title") + private String title; + @JsonProperty("state") + private String state; + @JsonProperty("html_url") + private String url; + @JsonProperty("labels") + private Label[] labels; + @JsonProperty("created_at") + private String createdAt; + @JsonProperty("closed_at") + private String closedAt; + + @JsonCreator + public Issue(@JsonProperty("id") long id, + @JsonProperty("number") long number, + @JsonProperty("title") String title, + @JsonProperty("state") String state, + @JsonProperty("html_url") String url, + @JsonProperty("labels") Label[] labels, + @JsonProperty("created_at") String createdAt, + @JsonProperty("closed_at") String closedAt) { + this.id = id; + this.number = number; + this.title = title; + this.state = state; + this.url = url; + this.labels = labels; + this.createdAt = createdAt; + this.closedAt = closedAt; + } + + public long getId() { + return id; + } + + public long getNumber() { + return number; + } + + public String getTitle() { + return title; + } + + public String getState() { + return state; + } + + public String getUrl() { + return url; + } + + public Label[] getLabels() { + return labels; + } + + public String getCreatedAt() { + return createdAt; + } + + public String getClosedAt() { + return closedAt; + } + } + + public static class IssueDetail extends Issue { + @JsonProperty("body") + private String body; + + @JsonCreator + public IssueDetail(@JsonProperty("id") long id, + @JsonProperty("number") long number, + @JsonProperty("title") String title, + @JsonProperty("state") String state, + @JsonProperty("html_url") String url, + @JsonProperty("labels") Label[] labels, + @JsonProperty("created_at") String createdAt, + @JsonProperty("closed_at") String closedAt, + @JsonProperty("body") String body) { + super(id, number, title, state, url, labels, createdAt, closedAt); + this.body = body; + } + + public String getBody() { + return body; + } + } + + public static class Label extends GitHubModel { + @JsonProperty("id") + private long id; + @JsonProperty("name") + private String name; + @JsonProperty("description") + private String description; + + @JsonCreator + public Label(@JsonProperty("id") long id, + @JsonProperty("name") String name, + @JsonProperty("description") String description) { + this.id = id; + this.name = name; + this.description = description; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + } +} diff --git a/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java new file mode 100644 index 000000000..f0bddee10 --- /dev/null +++ b/samples/semantickernel-learn-resources/src/main/java/com/microsoft/semantickernel/samples/plugins/github/GitHubPlugin.java @@ -0,0 +1,125 @@ +// Copyright (c) Microsoft. All rights reserved. +package com.microsoft.semantickernel.samples.plugins.github; + +import reactor.core.publisher.Mono; +import reactor.netty.http.client.HttpClient; +import com.microsoft.semantickernel.semanticfunctions.annotations.DefineKernelFunction; +import com.microsoft.semantickernel.semanticfunctions.annotations.KernelFunctionParameter; + +import java.io.IOException; +import java.util.List; + +public class GitHubPlugin { + public static final String baseUrl = "https://api.github.com"; + private final String token; + + public GitHubPlugin(String token) { + this.token = token; + } + + @DefineKernelFunction(name = "get_user_info", description = "Get user information from GitHub", returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$User") + public Mono getUserProfileAsync() { + HttpClient client = createClient(); + + return makeRequestAsync(client, "/user") + .map(json -> { + try { + return GitHubModel.objectMapper.readValue(json, GitHubModel.User.class); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubUser", e); + } + }); + } + + @DefineKernelFunction(name = "get_repo_info", description = "Get repository information from GitHub", returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$Repository") + public Mono getRepositoryAsync( + @KernelFunctionParameter(name = "organization", description = "The name of the repository to retrieve information for") String organization, + @KernelFunctionParameter(name = "repo_name", description = "The name of the repository to retrieve information for") String repoName) { + HttpClient client = createClient(); + + return makeRequestAsync(client, String.format("/repos/%s/%s", organization, repoName)) + .map(json -> { + try { + return GitHubModel.objectMapper.readValue(json, GitHubModel.Repository.class); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubRepository", e); + } + }); + } + + @DefineKernelFunction(name = "get_issues", description = "Get issues from GitHub", returnType = "java.util.List") + public Mono> getIssuesAsync( + @KernelFunctionParameter(name = "organization", description = "The name of the organization to retrieve issues for") String organization, + @KernelFunctionParameter(name = "repo_name", description = "The name of the repository to retrieve issues for") String repoName, + @KernelFunctionParameter(name = "max_results", description = "The maximum number of issues to retrieve", required = false, defaultValue = "10", type = int.class) int maxResults, + @KernelFunctionParameter(name = "state", description = "The state of the issues to retrieve", required = false, defaultValue = "open") String state, + @KernelFunctionParameter(name = "assignee", description = "The assignee of the issues to retrieve", required = false) String assignee) { + HttpClient client = createClient(); + + String query = String.format("/repos/%s/%s/issues", organization, repoName); + query = buildQueryString(query, "state", state); + query = buildQueryString(query, "assignee", assignee); + query = buildQueryString(query, "per_page", String.valueOf(maxResults)); + + return makeRequestAsync(client, query) + .flatMap(json -> { + try { + GitHubModel.Issue[] issues = GitHubModel.objectMapper.readValue(json, + GitHubModel.Issue[].class); + return Mono.just(List.of(issues)); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubIssues", e); + } + }); + } + + @DefineKernelFunction(name = "get_issue_detail_info", description = "Get detail information of a single issue from GitHub", returnType = "com.microsoft.semantickernel.samples.plugins.github.GitHubModel$IssueDetail") + public GitHubModel.IssueDetail getIssueDetailAsync( + @KernelFunctionParameter(name = "organization", description = "The name of the repository to retrieve information for") String organization, + @KernelFunctionParameter(name = "repo_name", description = "The name of the repository to retrieve information for") String repoName, + @KernelFunctionParameter(name = "issue_number", description = "The issue number to retrieve information for", type = int.class) int issueNumber) { + HttpClient client = createClient(); + + return makeRequestAsync(client, + String.format("/repos/%s/%s/issues/%d", organization, repoName, issueNumber)) + .map(json -> { + try { + return GitHubModel.objectMapper.readValue(json, GitHubModel.IssueDetail.class); + } catch (IOException e) { + throw new IllegalStateException("Failed to deserialize GitHubIssue", e); + } + }).block(); + } + + private HttpClient createClient() { + return HttpClient.create() + .baseUrl(baseUrl) + .headers(headers -> { + headers.add("User-Agent", "request"); + headers.add("Accept", "application/vnd.github+json"); + headers.add("Authorization", "Bearer " + token); + headers.add("X-GitHub-Api-Version", "2022-11-28"); + }); + } + + private static String buildQueryString(String path, String param, String value) { + if (value == null || value.isEmpty() + || value.equals(KernelFunctionParameter.NO_DEFAULT_VALUE)) { + return path; + } + + return path + (path.contains("?") ? "&" : "?") + param + "=" + value; + } + + private Mono makeRequestAsync(HttpClient client, String path) { + return client + .get() + .uri(path) + .responseSingle((res, content) -> { + if (res.status().code() != 200) { + return Mono.error(new IllegalStateException("Request failed: " + res.status())); + } + return content.asString(); + }); + } +} From d3c8fce441658813ff43095236e4983595e3bad1 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 5 May 2025 09:29:50 -0700 Subject: [PATCH 41/46] Add additional FunctionChoiceBehavior creators --- .../FunctionChoiceBehavior.java | 49 +++++++++++++++++-- .../NoneFunctionChoiceBehavior.java | 5 +- .../RequiredFunctionChoiceBehavior.java | 6 ++- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java index cbf64bde0..f00249524 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/FunctionChoiceBehavior.java @@ -66,6 +66,22 @@ public static FunctionChoiceBehavior auto(boolean autoInvoke) { return new AutoFunctionChoiceBehavior(autoInvoke, null, null); } + /** + * Gets an instance of the FunctionChoiceBehavior that provides either all the Kernel's plugins functions to the AI model to call or specific functions. + * + * @param autoInvoke Enable or disable auto-invocation. + * If auto-invocation is enabled, the model may request that the Semantic Kernel + * invoke the kernel functions and return the value to the model. + * @param functions Functions to provide to the model. If null, all the Kernel's plugins' functions are provided to the model. + * If empty, no functions are provided to the model, which is equivalent to disabling function calling. + * + * @return A new FunctionChoiceBehavior instance with all kernel functions allowed. + */ + public static FunctionChoiceBehavior auto(boolean autoInvoke, + @Nullable List> functions) { + return new AutoFunctionChoiceBehavior(autoInvoke, functions, null); + } + /** * Gets an instance of the FunctionChoiceBehavior that provides either all the Kernel's plugins functions to the AI model to call or specific functions. * @@ -79,11 +95,25 @@ public static FunctionChoiceBehavior auto(boolean autoInvoke) { * @return A new FunctionChoiceBehavior instance with all kernel functions allowed. */ public static FunctionChoiceBehavior auto(boolean autoInvoke, - List> functions, - @Nullable FunctionChoiceBehaviorOptions options) { + @Nullable List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { return new AutoFunctionChoiceBehavior(autoInvoke, functions, options); } + /** + * Gets an instance of the FunctionChoiceBehavior that provides either all the Kernel's plugins functions to the AI model to call or specific functions. + *

+ * This behavior forces the model to call the provided functions. + * SK connectors will invoke a requested function or multiple requested functions if the model requests multiple ones in one request, + * while handling the first request, and stop advertising the functions for the following requests to prevent the model from repeatedly calling the same function(s). + * + * @return A new FunctionChoiceBehavior instance with the required function. + */ + public static FunctionChoiceBehavior required(boolean autoInvoke, + @Nullable List> functions) { + return new RequiredFunctionChoiceBehavior(autoInvoke, functions, null); + } + /** * Gets an instance of the FunctionChoiceBehavior that provides either all the Kernel's plugins functions to the AI model to call or specific functions. *

@@ -96,11 +126,20 @@ public static FunctionChoiceBehavior auto(boolean autoInvoke, * @return A new FunctionChoiceBehavior instance with the required function. */ public static FunctionChoiceBehavior required(boolean autoInvoke, - List> functions, - @Nullable FunctionChoiceBehaviorOptions options) { + @Nullable List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { return new RequiredFunctionChoiceBehavior(autoInvoke, functions, options); } + /** + * Gets an instance of the FunctionChoiceBehavior that provides either all the Kernel's plugins functions to the AI model to call or specific functions. + *

+ * This behavior is useful if the user should first validate what functions the model will use. + */ + public static FunctionChoiceBehavior none() { + return new NoneFunctionChoiceBehavior(null, null); + } + /** * Gets an instance of the FunctionChoiceBehavior that provides either all the Kernel's plugins functions to the AI model to call or specific functions. *

@@ -109,7 +148,7 @@ public static FunctionChoiceBehavior required(boolean autoInvoke, * @param functions Functions to provide to the model. If null, all the Kernel's plugins' functions are provided to the model. * If empty, no functions are provided to the model, which is equivalent to disabling function calling. */ - public static FunctionChoiceBehavior none(List> functions, + public static FunctionChoiceBehavior none(@Nullable List> functions, @Nullable FunctionChoiceBehaviorOptions options) { return new NoneFunctionChoiceBehavior(functions, options); } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java index e5bef9f48..f0d247d36 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/NoneFunctionChoiceBehavior.java @@ -3,6 +3,7 @@ import com.microsoft.semantickernel.semanticfunctions.KernelFunction; +import javax.annotation.Nullable; import java.util.List; public class NoneFunctionChoiceBehavior extends FunctionChoiceBehavior { @@ -10,8 +11,8 @@ public class NoneFunctionChoiceBehavior extends FunctionChoiceBehavior { /** * Create a new instance of NoneFunctionChoiceBehavior. */ - public NoneFunctionChoiceBehavior(List> functions, - FunctionChoiceBehaviorOptions options) { + public NoneFunctionChoiceBehavior(@Nullable List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { super(functions, options); } } diff --git a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java index 01710cca3..ac1ae2bfe 100644 --- a/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java +++ b/semantickernel-api/src/main/java/com/microsoft/semantickernel/functionchoice/RequiredFunctionChoiceBehavior.java @@ -3,6 +3,7 @@ import com.microsoft.semantickernel.semanticfunctions.KernelFunction; +import javax.annotation.Nullable; import java.util.List; public class RequiredFunctionChoiceBehavior extends AutoFunctionChoiceBehavior { @@ -14,8 +15,9 @@ public class RequiredFunctionChoiceBehavior extends AutoFunctionChoiceBehavior { * @param functions A set of functions to advertise to the model. * @param options Options for the function choice behavior. */ - public RequiredFunctionChoiceBehavior(boolean autoInvoke, List> functions, - FunctionChoiceBehaviorOptions options) { + public RequiredFunctionChoiceBehavior(boolean autoInvoke, + @Nullable List> functions, + @Nullable FunctionChoiceBehaviorOptions options) { super(autoInvoke, functions, options); } } From 1bd792a0048733c3174e878ff13db0ced459b5be Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Mon, 5 May 2025 10:35:23 -0700 Subject: [PATCH 42/46] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0630f2071..d0a3d203e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.4.4-RC1 + +- Add Agent framework abstractions. +- Add ChatCompletionAgent implementation. +- Add FunctionChoiceBehavior for OpenAI, replacing the older ToolCallBehavior. + # 1.4.3 - Bug fix for execution on Android (https://github.com/microsoft/semantic-kernel-java/pull/284) From 4ea2ad0b9b72d55ae060106287399966a59bb5b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 May 2025 06:55:12 +0000 Subject: [PATCH 43/46] Bump net.sourceforge.pmd:pmd-core from 6.55.0 to 7.10.0 Bumps [net.sourceforge.pmd:pmd-core](https://github.com/pmd/pmd) from 6.55.0 to 7.10.0. - [Release notes](https://github.com/pmd/pmd/releases) - [Changelog](https://github.com/pmd/pmd/blob/main/docs/render_release_notes.rb) - [Commits](https://github.com/pmd/pmd/compare/pmd_releases/6.55.0...pmd_releases/7.10.0) --- updated-dependencies: - dependency-name: net.sourceforge.pmd:pmd-core dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0d31715dd..58fdd10e9 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ 5.14.2 0.9.1 - 6.55.0 + 7.10.0 UTF-8 microsoft/semantic-kernel git@github.com:${project.github.repository}.git From 479aef99475d3acfbd4a5c75e305730068b75a76 Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Tue, 6 May 2025 08:23:46 -0700 Subject: [PATCH 44/46] Set version to 1.4.4-RC-1-SNAPSHOT --- agents/semantickernel-agents-core/pom.xml | 2 +- aiservices/google/pom.xml | 2 +- aiservices/huggingface/pom.xml | 2 +- aiservices/openai/pom.xml | 2 +- api-test/integration-tests/pom.xml | 2 +- api-test/pom.xml | 2 +- data/semantickernel-data-azureaisearch/pom.xml | 2 +- data/semantickernel-data-jdbc/pom.xml | 2 +- data/semantickernel-data-redis/pom.xml | 2 +- pom.xml | 2 +- samples/pom.xml | 2 +- samples/semantickernel-concepts/pom.xml | 2 +- .../semantickernel-syntax-examples/pom.xml | 2 +- samples/semantickernel-demos/booking-agent-m365/pom.xml | 2 +- samples/semantickernel-demos/pom.xml | 2 +- .../semantickernel-demos/semantickernel-spring-starter/pom.xml | 2 +- samples/semantickernel-demos/sk-presidio-sample/pom.xml | 2 +- samples/semantickernel-learn-resources/pom.xml | 2 +- samples/semantickernel-sample-plugins/pom.xml | 2 +- .../semantickernel-openapi-plugin/pom.xml | 2 +- .../semantickernel-presidio-plugin/pom.xml | 2 +- .../semantickernel-text-splitter-plugin/pom.xml | 2 +- semantickernel-api/pom.xml | 2 +- semantickernel-experimental/pom.xml | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/agents/semantickernel-agents-core/pom.xml b/agents/semantickernel-agents-core/pom.xml index 4eec1b768..520f3e394 100644 --- a/agents/semantickernel-agents-core/pom.xml +++ b/agents/semantickernel-agents-core/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../../pom.xml diff --git a/aiservices/google/pom.xml b/aiservices/google/pom.xml index 97c6957c7..081adbd3b 100644 --- a/aiservices/google/pom.xml +++ b/aiservices/google/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../../pom.xml diff --git a/aiservices/huggingface/pom.xml b/aiservices/huggingface/pom.xml index 68803583a..c117eebfd 100644 --- a/aiservices/huggingface/pom.xml +++ b/aiservices/huggingface/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../../pom.xml diff --git a/aiservices/openai/pom.xml b/aiservices/openai/pom.xml index 56ad51830..21b1ecf6e 100644 --- a/aiservices/openai/pom.xml +++ b/aiservices/openai/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../../pom.xml diff --git a/api-test/integration-tests/pom.xml b/api-test/integration-tests/pom.xml index 49624531b..c929565e9 100644 --- a/api-test/integration-tests/pom.xml +++ b/api-test/integration-tests/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel api-test - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/api-test/pom.xml b/api-test/pom.xml index e5dde576c..fc05de7eb 100644 --- a/api-test/pom.xml +++ b/api-test/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/data/semantickernel-data-azureaisearch/pom.xml b/data/semantickernel-data-azureaisearch/pom.xml index 24cf4174c..27f09fcd5 100644 --- a/data/semantickernel-data-azureaisearch/pom.xml +++ b/data/semantickernel-data-azureaisearch/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../../pom.xml diff --git a/data/semantickernel-data-jdbc/pom.xml b/data/semantickernel-data-jdbc/pom.xml index 624779e98..9d60e939f 100644 --- a/data/semantickernel-data-jdbc/pom.xml +++ b/data/semantickernel-data-jdbc/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../../pom.xml diff --git a/data/semantickernel-data-redis/pom.xml b/data/semantickernel-data-redis/pom.xml index 69e7c293d..9eb7dc4cf 100644 --- a/data/semantickernel-data-redis/pom.xml +++ b/data/semantickernel-data-redis/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../../pom.xml diff --git a/pom.xml b/pom.xml index 0d31715dd..288195d64 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT pom https://www.github.com/microsoft/semantic-kernel diff --git a/samples/pom.xml b/samples/pom.xml index d42af3c9e..0f6b2e57c 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-concepts/pom.xml b/samples/semantickernel-concepts/pom.xml index d94740e8a..3ee3d98f1 100644 --- a/samples/semantickernel-concepts/pom.xml +++ b/samples/semantickernel-concepts/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml b/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml index 3ccc114c1..c0aa53bc8 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-concepts - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-demos/booking-agent-m365/pom.xml b/samples/semantickernel-demos/booking-agent-m365/pom.xml index d7a6ec3b5..17604eecd 100644 --- a/samples/semantickernel-demos/booking-agent-m365/pom.xml +++ b/samples/semantickernel-demos/booking-agent-m365/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-demos - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-demos/pom.xml b/samples/semantickernel-demos/pom.xml index eb3c0afe9..2c2631d5a 100644 --- a/samples/semantickernel-demos/pom.xml +++ b/samples/semantickernel-demos/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml b/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml index bea07af99..3f21997dc 100644 --- a/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml +++ b/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-demos - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-demos/sk-presidio-sample/pom.xml b/samples/semantickernel-demos/sk-presidio-sample/pom.xml index 799d563b9..fa4e6a08e 100644 --- a/samples/semantickernel-demos/sk-presidio-sample/pom.xml +++ b/samples/semantickernel-demos/sk-presidio-sample/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-demos - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-learn-resources/pom.xml b/samples/semantickernel-learn-resources/pom.xml index 293da2d3d..a7024dbce 100644 --- a/samples/semantickernel-learn-resources/pom.xml +++ b/samples/semantickernel-learn-resources/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-sample-plugins/pom.xml b/samples/semantickernel-sample-plugins/pom.xml index bb8db1393..99e24e008 100644 --- a/samples/semantickernel-sample-plugins/pom.xml +++ b/samples/semantickernel-sample-plugins/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml index fa9f378d0..afc4af3fe 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml +++ b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-sample-plugins - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml b/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml index 8c012a6e1..75722db87 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml +++ b/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-sample-plugins - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml b/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml index a10f1cfcc..1e67c8e6e 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml +++ b/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-sample-plugins - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/semantickernel-api/pom.xml b/semantickernel-api/pom.xml index 3176c82e6..bc0a2c423 100644 --- a/semantickernel-api/pom.xml +++ b/semantickernel-api/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT ../pom.xml diff --git a/semantickernel-experimental/pom.xml b/semantickernel-experimental/pom.xml index 1b3aa7847..a6771b23c 100644 --- a/semantickernel-experimental/pom.xml +++ b/semantickernel-experimental/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT semantickernel-experimental From 54512fb5f1cd5c716d3b801a9f1e3ad6b680b27b Mon Sep 17 00:00:00 2001 From: Milder Hernandez Cagua Date: Tue, 6 May 2025 08:39:29 -0700 Subject: [PATCH 45/46] Update bom pom --- semantickernel-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/semantickernel-bom/pom.xml b/semantickernel-bom/pom.xml index 32ca102b1..672af9b6b 100644 --- a/semantickernel-bom/pom.xml +++ b/semantickernel-bom/pom.xml @@ -5,7 +5,7 @@ com.microsoft.semantic-kernel semantickernel-bom - 1.4.4-SNAPSHOT + 1.4.4-RC1-SNAPSHOT pom Semantic Kernel Java BOM From f1dee5f2e21e83aac182d93181e78f25b063c5f3 Mon Sep 17 00:00:00 2001 From: GitHub Date: Tue, 6 May 2025 08:49:43 -0700 Subject: [PATCH 46/46] [maven-release-plugin] prepare release java-1.4.4-RC1 --- agents/semantickernel-agents-core/pom.xml | 6 ++---- aiservices/google/pom.xml | 2 +- aiservices/huggingface/pom.xml | 2 +- aiservices/openai/pom.xml | 2 +- api-test/integration-tests/pom.xml | 2 +- api-test/pom.xml | 2 +- data/semantickernel-data-azureaisearch/pom.xml | 2 +- data/semantickernel-data-jdbc/pom.xml | 2 +- data/semantickernel-data-redis/pom.xml | 2 +- pom.xml | 4 ++-- samples/pom.xml | 2 +- samples/semantickernel-concepts/pom.xml | 2 +- .../semantickernel-syntax-examples/pom.xml | 2 +- samples/semantickernel-demos/booking-agent-m365/pom.xml | 2 +- samples/semantickernel-demos/pom.xml | 2 +- .../semantickernel-spring-starter/pom.xml | 2 +- samples/semantickernel-demos/sk-presidio-sample/pom.xml | 2 +- samples/semantickernel-learn-resources/pom.xml | 2 +- samples/semantickernel-sample-plugins/pom.xml | 2 +- .../semantickernel-openapi-plugin/pom.xml | 2 +- .../semantickernel-presidio-plugin/pom.xml | 2 +- .../semantickernel-text-splitter-plugin/pom.xml | 2 +- semantickernel-api/pom.xml | 2 +- semantickernel-bom/pom.xml | 4 ++-- semantickernel-experimental/pom.xml | 2 +- 25 files changed, 28 insertions(+), 30 deletions(-) diff --git a/agents/semantickernel-agents-core/pom.xml b/agents/semantickernel-agents-core/pom.xml index 520f3e394..162868ee6 100644 --- a/agents/semantickernel-agents-core/pom.xml +++ b/agents/semantickernel-agents-core/pom.xml @@ -1,12 +1,10 @@ - + 4.0.0 com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../../pom.xml diff --git a/aiservices/google/pom.xml b/aiservices/google/pom.xml index 081adbd3b..22b492d79 100644 --- a/aiservices/google/pom.xml +++ b/aiservices/google/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../../pom.xml diff --git a/aiservices/huggingface/pom.xml b/aiservices/huggingface/pom.xml index c117eebfd..6ae919477 100644 --- a/aiservices/huggingface/pom.xml +++ b/aiservices/huggingface/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../../pom.xml diff --git a/aiservices/openai/pom.xml b/aiservices/openai/pom.xml index 21b1ecf6e..e826dcc11 100644 --- a/aiservices/openai/pom.xml +++ b/aiservices/openai/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../../pom.xml diff --git a/api-test/integration-tests/pom.xml b/api-test/integration-tests/pom.xml index c929565e9..f6c51af78 100644 --- a/api-test/integration-tests/pom.xml +++ b/api-test/integration-tests/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel api-test - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/api-test/pom.xml b/api-test/pom.xml index fc05de7eb..a60112908 100644 --- a/api-test/pom.xml +++ b/api-test/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/data/semantickernel-data-azureaisearch/pom.xml b/data/semantickernel-data-azureaisearch/pom.xml index 27f09fcd5..b27936031 100644 --- a/data/semantickernel-data-azureaisearch/pom.xml +++ b/data/semantickernel-data-azureaisearch/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../../pom.xml diff --git a/data/semantickernel-data-jdbc/pom.xml b/data/semantickernel-data-jdbc/pom.xml index 9d60e939f..ab4dfe5e8 100644 --- a/data/semantickernel-data-jdbc/pom.xml +++ b/data/semantickernel-data-jdbc/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../../pom.xml diff --git a/data/semantickernel-data-redis/pom.xml b/data/semantickernel-data-redis/pom.xml index 9eb7dc4cf..871fc9310 100644 --- a/data/semantickernel-data-redis/pom.xml +++ b/data/semantickernel-data-redis/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../../pom.xml diff --git a/pom.xml b/pom.xml index 75d35d71f..b8fef17f6 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 pom https://www.github.com/microsoft/semantic-kernel @@ -838,6 +838,6 @@ https://github.com/microsoft/semantic-kernel scm:git:https://github.com/microsoft/semantic-kernel.git scm:git:https://github.com/microsoft/semantic-kernel.git - HEAD + java-1.4.4-RC1 diff --git a/samples/pom.xml b/samples/pom.xml index 0f6b2e57c..aa9e46050 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-concepts/pom.xml b/samples/semantickernel-concepts/pom.xml index 3ee3d98f1..4adace8fb 100644 --- a/samples/semantickernel-concepts/pom.xml +++ b/samples/semantickernel-concepts/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml b/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml index c0aa53bc8..700f42c3e 100644 --- a/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml +++ b/samples/semantickernel-concepts/semantickernel-syntax-examples/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-concepts - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-demos/booking-agent-m365/pom.xml b/samples/semantickernel-demos/booking-agent-m365/pom.xml index 17604eecd..fb1461f56 100644 --- a/samples/semantickernel-demos/booking-agent-m365/pom.xml +++ b/samples/semantickernel-demos/booking-agent-m365/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-demos - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-demos/pom.xml b/samples/semantickernel-demos/pom.xml index 2c2631d5a..7637b820a 100644 --- a/samples/semantickernel-demos/pom.xml +++ b/samples/semantickernel-demos/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml b/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml index 3f21997dc..30d23e794 100644 --- a/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml +++ b/samples/semantickernel-demos/semantickernel-spring-starter/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-demos - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-demos/sk-presidio-sample/pom.xml b/samples/semantickernel-demos/sk-presidio-sample/pom.xml index fa4e6a08e..ff5520d79 100644 --- a/samples/semantickernel-demos/sk-presidio-sample/pom.xml +++ b/samples/semantickernel-demos/sk-presidio-sample/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-demos - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-learn-resources/pom.xml b/samples/semantickernel-learn-resources/pom.xml index a7024dbce..338394719 100644 --- a/samples/semantickernel-learn-resources/pom.xml +++ b/samples/semantickernel-learn-resources/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-sample-plugins/pom.xml b/samples/semantickernel-sample-plugins/pom.xml index 99e24e008..6f8185b0b 100644 --- a/samples/semantickernel-sample-plugins/pom.xml +++ b/samples/semantickernel-sample-plugins/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-samples-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml index afc4af3fe..085a462f0 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml +++ b/samples/semantickernel-sample-plugins/semantickernel-openapi-plugin/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-sample-plugins - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml b/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml index 75722db87..78b75aac4 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml +++ b/samples/semantickernel-sample-plugins/semantickernel-presidio-plugin/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-sample-plugins - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml b/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml index 1e67c8e6e..906b62db6 100644 --- a/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml +++ b/samples/semantickernel-sample-plugins/semantickernel-text-splitter-plugin/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-sample-plugins - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/semantickernel-api/pom.xml b/semantickernel-api/pom.xml index bc0a2c423..06e1ebc06 100644 --- a/semantickernel-api/pom.xml +++ b/semantickernel-api/pom.xml @@ -6,7 +6,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 ../pom.xml diff --git a/semantickernel-bom/pom.xml b/semantickernel-bom/pom.xml index 672af9b6b..2fbb78917 100644 --- a/semantickernel-bom/pom.xml +++ b/semantickernel-bom/pom.xml @@ -5,7 +5,7 @@ com.microsoft.semantic-kernel semantickernel-bom - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 pom Semantic Kernel Java BOM @@ -296,6 +296,6 @@ https://github.com/microsoft/semantic-kernel scm:git:https://github.com/microsoft/semantic-kernel.git scm:git:https://github.com/microsoft/semantic-kernel.git - HEAD + java-1.4.4-RC1 diff --git a/semantickernel-experimental/pom.xml b/semantickernel-experimental/pom.xml index a6771b23c..cb34ede62 100644 --- a/semantickernel-experimental/pom.xml +++ b/semantickernel-experimental/pom.xml @@ -4,7 +4,7 @@ com.microsoft.semantic-kernel semantickernel-parent - 1.4.4-RC1-SNAPSHOT + 1.4.4-RC1 semantickernel-experimental