Fix formatting (#1492)

This commit is contained in:
Bruno Borges
2023-06-15 17:34:56 -07:00
committed by GitHub
parent cb7abb3748
commit bdbdc90661
16 changed files with 593 additions and 567 deletions
@@ -1,12 +1,12 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.ai.embeddings;
import java.util.List;
import com.azure.ai.openai.OpenAIAsyncClient;
import reactor.core.publisher.Mono;
import java.util.List;
/** Interface for text embedding generation services */
public interface EmbeddingGeneration<TValue, TEmbedding extends Number> {
/**
@@ -1,17 +1,17 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.chatcompletion;
import javax.annotation.Nullable;
import com.azure.ai.openai.OpenAIAsyncClient;
import reactor.core.publisher.Mono;
import javax.annotation.Nullable;
public interface ChatCompletion<ChatHistoryType extends ChatHistory> {
/**
* Generate a new chat message
*
* @param chat Chat history
* @param chat Chat history
* @param requestSettings AI request settings
* @return Generated chat message in string format
*/
@@ -1,12 +1,12 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.textcompletion;
import java.util.List;
import com.azure.ai.openai.OpenAIAsyncClient;
import reactor.core.publisher.Mono;
import java.util.List;
/** Interface for text completion services */
public interface TextCompletion {
// TODO: Support Cancellation Token
@@ -14,15 +14,14 @@ public interface TextCompletion {
/**
* Creates a completion for the prompt and settings.
*
* @param text The prompt to complete.
* @param text The prompt to complete.
* @param requestSettings Request settings for the completion API
* @return Text generated by the remote model
*/
Mono<List<String>> completeAsync(String text, CompletionRequestSettings requestSettings);
abstract class Builder {
protected Builder() {
}
protected Builder() {}
public abstract TextCompletion build(OpenAIAsyncClient client, String modelId);
}
@@ -1,11 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.connectors.ai.openai.chatcompletion;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.models.ChatCompletionsOptions;
import com.azure.ai.openai.models.ChatMessage;
@@ -19,6 +14,11 @@ import com.microsoft.semantickernel.connectors.ai.openai.azuresdk.ClientBase;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
/** OpenAI chat completion client. */
public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<OpenAIChatHistory> {
public OpenAIChatCompletion(OpenAIAsyncClient client, String modelId) {
@@ -26,8 +26,7 @@ public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<O
}
public static class Builder implements ChatCompletion.Builder {
public Builder() {
}
public Builder() {}
public ChatCompletion<OpenAIChatHistory> build(OpenAIAsyncClient client, String modelId) {
return new OpenAIChatCompletion(client, modelId);
@@ -37,7 +36,7 @@ public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<O
/**
* Generate a new chat message
*
* @param chat Chat history
* @param chat Chat history
* @param requestSettings AI request settings
* @return The response generated by the request
*/
@@ -53,7 +52,7 @@ public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<O
/**
* Generate a new chat message
*
* @param chat Chat history
* @param chat Chat history
* @param requestSettings AI request settings
* @return The response generated by the request
*/
@@ -83,13 +82,14 @@ public class OpenAIChatCompletion extends ClientBase implements ChatCompletion<O
private static ChatCompletionsOptions createChatCompletionsOptions(
ChatRequestSettings requestSettings, ChatHistory chat) {
List<ChatMessage> messages = chat.getMessages().stream()
.map(
it -> {
return new ChatMessage(toChatRole(it.getAuthorRoles()))
.setContent(it.getContent());
})
.collect(Collectors.toList());
List<ChatMessage> messages =
chat.getMessages().stream()
.map(
it -> {
return new ChatMessage(toChatRole(it.getAuthorRoles()))
.setContent(it.getContent());
})
.collect(Collectors.toList());
ChatCompletionsOptions options = new ChatCompletionsOptions(messages);
@@ -1,12 +1,12 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.connectors.ai.openai.textcompletion;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.models.Choice;
import com.azure.ai.openai.models.Completions;
import com.azure.ai.openai.models.CompletionsOptions;
import com.microsoft.semantickernel.ai.AIException;
import com.microsoft.semantickernel.connectors.ai.openai.azuresdk.ClientBase;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.microsoft.semantickernel.textcompletion.CompletionRequestSettings;
import com.microsoft.semantickernel.textcompletion.TextCompletion;
@@ -51,14 +51,15 @@ public class OpenAITextCompletion extends ClientBase implements TextCompletion {
throw new AIException(AIException.ErrorCodes.InvalidRequest, "Max tokens must be >0");
}
CompletionsOptions completionsOptions = new CompletionsOptions(Collections.singletonList(text))
.setMaxTokens(requestSettings.getMaxTokens())
.setTemperature(requestSettings.getTemperature())
.setTopP(requestSettings.getTopP())
.setFrequencyPenalty(requestSettings.getFrequencyPenalty())
.setPresencePenalty(requestSettings.getPresencePenalty())
.setModel(getModelId())
.setUser(null);
CompletionsOptions completionsOptions =
new CompletionsOptions(Collections.singletonList(text))
.setMaxTokens(requestSettings.getMaxTokens())
.setTemperature(requestSettings.getTemperature())
.setTopP(requestSettings.getTopP())
.setFrequencyPenalty(requestSettings.getFrequencyPenalty())
.setPresencePenalty(requestSettings.getPresencePenalty())
.setModel(getModelId())
.setUser(null);
return getClient()
.getCompletions(getModelId(), completionsOptions)
@@ -1,9 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.connectors.ai.openai.textembeddings;
import java.util.List;
import java.util.stream.Collectors;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.models.EmbeddingItem;
import com.azure.ai.openai.models.Embeddings;
@@ -14,6 +11,9 @@ import com.microsoft.semantickernel.connectors.ai.openai.azuresdk.ClientBase;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.stream.Collectors;
public class OpenAITextEmbeddingGeneration extends ClientBase
implements EmbeddingGeneration<String, Float> {
@@ -34,9 +34,10 @@ public class OpenAITextEmbeddingGeneration extends ClientBase
.flatMapIterable(Embeddings::getData)
.mapNotNull(EmbeddingItem::getEmbedding)
.map(
embedding -> embedding.stream()
.map(Double::floatValue)
.collect(Collectors.toList()))
embedding ->
embedding.stream()
.map(Double::floatValue)
.collect(Collectors.toList()))
.mapNotNull(Embedding::new)
.collectList();
}
@@ -260,9 +260,7 @@ public class TextChunkerTest {
"This is only a test",
"We repeat, this is only a test, A unit test",
"A small note, And another, And once again, Seriously,",
"this is the end, We're finished, All set, Bye."
+ "\n"
+ "Done.");
"this is the end, We're finished, All set, Bye." + "\n" + "Done.");
List<String> result = TextChunker.splitPlainTextParagraphs(input, 15);
@@ -307,9 +305,7 @@ public class TextChunkerTest {
"broadcast system-This is only a test",
"We repeat-this is only a test-A unit test",
"A small note-And another-And once again-Seriously,",
"this is the end-We're finished-All set-Bye."
+ "\n"
+ "Done.");
"this is the end-We're finished-All set-Bye." + "\n" + "Done.");
List<String> result = TextChunker.splitPlainTextParagraphs(input, 15);
@@ -327,9 +323,7 @@ public class TextChunkerTest {
"SeriouslythisistheendWe'refinishedAllsetByeDoneThisOneWillBeSplitToMeetTheLimit");
List<String> expected =
Arrays.asList(
"Thisisatestoftheemergencybroadcastsystem"
+ "\n"
+ "Thisisonlyatest",
"Thisisatestoftheemergencybroadcastsystem" + "\n" + "Thisisonlyatest",
"WerepeatthisisonlyatestAunittest",
"AsmallnoteAndanotherAndonceagain",
"SeriouslythisistheendWe'refinishedAllse",
@@ -1,17 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mockito;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.models.Choice;
import com.azure.ai.openai.models.Completions;
@@ -26,219 +15,237 @@ import com.microsoft.semantickernel.textcompletion.CompletionSKContext;
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
import com.microsoft.semantickernel.textcompletion.TextCompletion;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher;
import org.mockito.Mockito;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class DefaultKernelTest {
@Test
void contextVariableTest() {
String model = "a-model";
@Test
void contextVariableTest() {
String model = "a-model";
OpenAIAsyncClient client = mockCompletionOpenAIAsyncClient(
Tuples.of("A", "a"), Tuples.of("user: Aauser: B", "b"));
OpenAIAsyncClient client =
mockCompletionOpenAIAsyncClient(
Tuples.of("A", "a"), Tuples.of("user: Aauser: B", "b"));
Kernel kernel = buildKernel(model, client);
Kernel kernel = buildKernel(model, client);
String prompt = "{{$history}}user: {{$user_input}}\n";
String prompt = "{{$history}}user: {{$user_input}}\n";
CompletionSKFunction chat = kernel.getSemanticFunctionBuilder()
.createFunction(
prompt,
"ChatBot",
null,
null,
new PromptTemplateConfig.CompletionConfig(
0.7, 0.5, 0, 0, 2000, new ArrayList<>()));
CompletionSKFunction chat =
kernel.getSemanticFunctionBuilder()
.createFunction(
prompt,
"ChatBot",
null,
null,
new PromptTemplateConfig.CompletionConfig(
0.7, 0.5, 0, 0, 2000, new ArrayList<>()));
ContextVariables variables = SKBuilders.variables().build();
ContextVariables variables = SKBuilders.variables().build();
CompletionSKContext readOnlySkContext = chat.buildContext(variables, null, null)
.setVariable("history", "")
.setVariable("user_input", "A");
CompletionSKContext readOnlySkContext =
chat.buildContext(variables, null, null)
.setVariable("history", "")
.setVariable("user_input", "A");
CompletionSKContext result = chat.invokeAsync(readOnlySkContext, null).block();
CompletionSKContext result = chat.invokeAsync(readOnlySkContext, null).block();
if (result == null) {
Assertions.fail();
}
Assertions.assertEquals("a", result.getResult());
result = result.appendToVariable("history", "user: A" + result.getResult())
.setVariable("user_input", "B");
result = chat.invokeAsync(result, null).block();
if (result == null) {
Assertions.fail();
}
Assertions.assertEquals("b", result.getResult());
if (result == null) {
Assertions.fail();
}
@Test
void tellAJoke() {
String expectedResponse = "a result joke";
OpenAIAsyncClient client = mockCompletionOpenAIAsyncClient("WRITE", expectedResponse);
String model = "a-model-name";
Kernel kernel = buildKernel(model, client);
Assertions.assertEquals("a", result.getResult());
CompletionSKFunction function = kernel.importSkill(
result =
result.appendToVariable("history", "user: A" + result.getResult())
.setVariable("user_input", "B");
result = chat.invokeAsync(result, null).block();
if (result == null) {
Assertions.fail();
}
Assertions.assertEquals("b", result.getResult());
}
@Test
void tellAJoke() {
String expectedResponse = "a result joke";
OpenAIAsyncClient client = mockCompletionOpenAIAsyncClient("WRITE", expectedResponse);
String model = "a-model-name";
Kernel kernel = buildKernel(model, client);
CompletionSKFunction function =
kernel.importSkill(
"FunSkill",
KernelExtensions.importSemanticSkillFromDirectory(
"../../samples/skills", "FunSkill"))
.getFunction("joke", CompletionSKFunction.class);
"../../samples/skills", "FunSkill"))
.getFunction("joke", CompletionSKFunction.class);
Mono<CompletionSKContext> mono = function.invokeAsync("time travel to dinosaur age");
CompletionSKContext result = mono.block();
Mono<CompletionSKContext> mono = function.invokeAsync("time travel to dinosaur age");
CompletionSKContext result = mono.block();
String expected = "WRITE EXACTLY ONE JOKE or HUMOROUS STORY ABOUT THE TOPIC BELOW\n"
+ "\n"
+ "JOKE MUST BE:\n"
+ "- G RATED\n"
+ "- WORKPLACE/FAMILY SAFE\n"
+ "NO SEXISM, RACISM OR OTHER BIAS/BIGOTRY\n"
+ "\n"
+ "BE CREATIVE AND FUNNY. I WANT TO LAUGH.\n"
+ "\n"
+ "+++++\n"
+ "\n"
+ "time travel to dinosaur age\n"
+ "+++++\n";
String expected =
"WRITE EXACTLY ONE JOKE or HUMOROUS STORY ABOUT THE TOPIC BELOW\n"
+ "\n"
+ "JOKE MUST BE:\n"
+ "- G RATED\n"
+ "- WORKPLACE/FAMILY SAFE\n"
+ "NO SEXISM, RACISM OR OTHER BIAS/BIGOTRY\n"
+ "\n"
+ "BE CREATIVE AND FUNNY. I WANT TO LAUGH.\n"
+ "\n"
+ "+++++\n"
+ "\n"
+ "time travel to dinosaur age\n"
+ "+++++\n";
assertCompletionsWasCalledWithModelAndText(client, model, expected);
assertCompletionsWasCalledWithModelAndText(client, model, expected);
assertTheResultEquals(result, expectedResponse);
assertTheResultEquals(result, expectedResponse);
}
public static Kernel buildKernel(String model, OpenAIAsyncClient client) {
TextCompletion textCompletion = new OpenAITextCompletion(client, model);
KernelConfig kernelConfig =
SKBuilders.kernelConfig()
.addTextCompletionService(model, kernel -> textCompletion)
.build();
return SKBuilders.kernel().setKernelConfig(kernelConfig).build();
}
private static OpenAIAsyncClient mockCompletionOpenAIAsyncClient(String arg, String response) {
List<Tuple2<String, String>> responses =
Collections.singletonList(Tuples.of(arg, response));
return mockCompletionOpenAIAsyncClient(responses.toArray(new Tuple2[0]));
}
/*
* Mocks a Text Completion client where if the prompt matches it will return the
* first arg it will return the response,
* i.e:
*
* mockCompletionOpenAIAsyncClient(
* List.<>of(
* Tuples.of("Tell me a joke", "This is a joke")
* )
* );
*
* This if the client is prompted with "Tell me a joke", the mocked client would
* respond with "This is a joke"
*/
public static OpenAIAsyncClient mockCompletionOpenAIAsyncClient(
Tuple2<String, String>... responses) {
List<Tuple2<ArgumentMatcher<String>, String>> matchers =
Arrays.stream(responses)
.map(
response ->
Tuples.<ArgumentMatcher<String>, String>of(
arg -> arg.contains(response.getT1()),
response.getT2()))
.collect(Collectors.toList());
return mockCompletionOpenAIAsyncClientMatchers(matchers.toArray(new Tuple2[0]));
}
public static OpenAIAsyncClient mockCompletionOpenAIAsyncClientMatchers(
Tuple2<ArgumentMatcher<String>, String>... responses) {
OpenAIAsyncClient openAIAsyncClient = Mockito.mock(OpenAIAsyncClient.class);
for (Tuple2<ArgumentMatcher<String>, String> response : responses) {
Choice choice = Mockito.mock(Choice.class);
Mockito.when(choice.getText()).thenReturn(response.getT2());
Completions completions = Mockito.mock(Completions.class);
Mockito.when(completions.getChoices()).thenReturn(Collections.singletonList(choice));
Mockito.when(
openAIAsyncClient.getCompletions(
Mockito.any(String.class),
Mockito.<CompletionsOptions>argThat(
it -> response.getT1().matches(it.getPrompt().get(0)))))
.thenReturn(Mono.just(completions));
Mockito.when(
openAIAsyncClient.getCompletions(
Mockito.any(String.class),
Mockito.<String>argThat(it -> response.getT1().matches(it))))
.thenReturn(Mono.just(completions));
}
return openAIAsyncClient;
}
public static Kernel buildKernel(String model, OpenAIAsyncClient client) {
@Test
void inlineFunctionTest() {
TextCompletion textCompletion = new OpenAITextCompletion(client, model);
String model = "a-model";
KernelConfig kernelConfig = SKBuilders.kernelConfig()
.addTextCompletionService(model, kernel -> textCompletion)
.build();
String expectedResponse = "foo";
OpenAIAsyncClient openAIAsyncClient =
mockCompletionOpenAIAsyncClient("block", expectedResponse);
return SKBuilders.kernel().setKernelConfig(kernelConfig).build();
}
Kernel kernel = buildKernel(model, openAIAsyncClient);
private static OpenAIAsyncClient mockCompletionOpenAIAsyncClient(String arg, String response) {
List<Tuple2<String, String>> responses = Collections.singletonList(Tuples.of(arg, response));
String text = "A block of text\n";
return mockCompletionOpenAIAsyncClient(responses.toArray(new Tuple2[0]));
}
String prompt = "{{$input}}\n" + "Summarize the content above.";
/*
* Mocks a Text Completion client where if the prompt matches it will return the
* first arg it will return the response,
* i.e:
*
* mockCompletionOpenAIAsyncClient(
* List.<>of(
* Tuples.of("Tell me a joke", "This is a joke")
* )
* );
*
* This if the client is prompted with "Tell me a joke", the mocked client would
* respond with "This is a joke"
*/
CompletionSKFunction summarize =
SKBuilders.completionFunctions()
.createFunction(
prompt,
"summarize",
null,
null,
new PromptTemplateConfig.CompletionConfig(
0.2, 0.5, 0, 0, 2000, new ArrayList<>()));
kernel.registerSemanticFunction(summarize);
public static OpenAIAsyncClient mockCompletionOpenAIAsyncClient(
Tuple2<String, String>... responses) {
Mono<CompletionSKContext> mono = summarize.invokeAsync(text);
CompletionSKContext result = mono.block();
List<Tuple2<ArgumentMatcher<String>, String>> matchers = Arrays.stream(responses)
.map(
response -> Tuples.<ArgumentMatcher<String>, String>of(
arg -> arg.contains(response.getT1()),
response.getT2()))
.collect(Collectors.toList());
String expected = "A block of text\n\nSummarize the content above.";
return mockCompletionOpenAIAsyncClientMatchers(matchers.toArray(new Tuple2[0]));
}
assertCompletionsWasCalledWithModelAndText(openAIAsyncClient, model, expected);
assertTheResultEquals(result, expectedResponse);
}
public static OpenAIAsyncClient mockCompletionOpenAIAsyncClientMatchers(
Tuple2<ArgumentMatcher<String>, String>... responses) {
OpenAIAsyncClient openAIAsyncClient = Mockito
.mock(OpenAIAsyncClient.class);
private void assertTheResultEquals(SKContext result, String expected) {
Assertions.assertEquals(expected, result.getResult());
}
for (Tuple2<ArgumentMatcher<String>, String> response : responses) {
private static void assertCompletionsWasCalledWithModelAndText(
OpenAIAsyncClient openAIAsyncClient, String model, String expected) {
Choice choice = Mockito.mock(Choice.class);
Mockito.when(choice.getText()).thenReturn(response.getT2());
Completions completions = Mockito.mock(Completions.class);
Mockito.when(completions.getChoices()).thenReturn(Collections.singletonList(choice));
Mockito.when(
openAIAsyncClient.getCompletions(
Mockito.any(String.class),
Mockito.<CompletionsOptions>argThat(
it -> response.getT1().matches(
it.getPrompt().get(0)))))
.thenReturn(Mono.just(completions));
Mockito.when(
openAIAsyncClient.getCompletions(
Mockito.any(String.class),
Mockito.<String>argThat(
it -> response.getT1().matches(it))))
.thenReturn(Mono.just(completions));
}
return openAIAsyncClient;
}
@Test
void inlineFunctionTest() {
String model = "a-model";
String expectedResponse = "foo";
OpenAIAsyncClient openAIAsyncClient = mockCompletionOpenAIAsyncClient("block", expectedResponse);
Kernel kernel = buildKernel(model, openAIAsyncClient);
String text = "A block of text\n";
String prompt = "{{$input}}\n" + "Summarize the content above.";
CompletionSKFunction summarize = SKBuilders.completionFunctions()
.createFunction(
prompt,
"summarize",
null,
null,
new PromptTemplateConfig.CompletionConfig(
0.2, 0.5, 0, 0, 2000, new ArrayList<>()));
kernel.registerSemanticFunction(summarize);
Mono<CompletionSKContext> mono = summarize.invokeAsync(text);
CompletionSKContext result = mono.block();
String expected = "A block of text\n\nSummarize the content above.";
assertCompletionsWasCalledWithModelAndText(openAIAsyncClient, model, expected);
assertTheResultEquals(result, expectedResponse);
}
private void assertTheResultEquals(SKContext result, String expected) {
Assertions.assertEquals(expected, result.getResult());
}
private static void assertCompletionsWasCalledWithModelAndText(
OpenAIAsyncClient openAIAsyncClient, String model, String expected) {
Mockito.verify(openAIAsyncClient, Mockito.times(1))
.getCompletions(
Mockito.matches(model),
Mockito.<CompletionsOptions>argThat(
completionsOptions -> completionsOptions
.getPrompt()
.size() == 1
&& completionsOptions
.getPrompt()
.get(0)
.equals(expected)));
}
Mockito.verify(openAIAsyncClient, Mockito.times(1))
.getCompletions(
Mockito.matches(model),
Mockito.<CompletionsOptions>argThat(
completionsOptions ->
completionsOptions.getPrompt().size() == 1
&& completionsOptions
.getPrompt()
.get(0)
.equals(expected)));
}
}
@@ -1,67 +1,67 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.models.EmbeddingItem;
import com.azure.ai.openai.models.Embeddings;
import com.microsoft.semantickernel.ai.embeddings.EmbeddingGeneration;
import com.microsoft.semantickernel.connectors.ai.openai.textembeddings.OpenAITextEmbeddingGeneration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TextEmbeddingsTest {
private static OpenAIAsyncClient mockEmbeddingOpenAIAsyncClient() {
OpenAIAsyncClient openAIAsyncClient = Mockito.mock(OpenAIAsyncClient.class);
Embeddings embeddings = Mockito.mock(Embeddings.class);
EmbeddingItem embeddingItem = Mockito.mock(EmbeddingItem.class);
private static OpenAIAsyncClient mockEmbeddingOpenAIAsyncClient() {
OpenAIAsyncClient openAIAsyncClient = Mockito.mock(OpenAIAsyncClient.class);
Embeddings embeddings = Mockito.mock(Embeddings.class);
EmbeddingItem embeddingItem = Mockito.mock(EmbeddingItem.class);
Mockito.when(embeddingItem.getEmbedding()).thenReturn(Collections.singletonList(1.0));
Mockito.when(embeddingItem.getEmbedding()).thenReturn(Collections.singletonList(1.0));
Mockito.when(embeddings.getData()).thenReturn(Collections.singletonList(embeddingItem));
Mockito.when(embeddings.getData()).thenReturn(Collections.singletonList(embeddingItem));
Mockito.when(
openAIAsyncClient.getEmbeddings(
Mockito.any(String.class),
Mockito.argThat(
it -> it != null
&& it.getModel()
.equals("text-embedding-ada-002"))))
.thenReturn(Mono.just(embeddings));
Mockito.when(
openAIAsyncClient.getEmbeddings(
Mockito.any(String.class),
Mockito.argThat(
it ->
it != null
&& it.getModel()
.equals("text-embedding-ada-002"))))
.thenReturn(Mono.just(embeddings));
return openAIAsyncClient;
}
return openAIAsyncClient;
}
@Test
public void testEmbedding() {
testEmbeddingGeneration(mockEmbeddingOpenAIAsyncClient(), 1);
}
@Test
public void testEmbedding() {
testEmbeddingGeneration(mockEmbeddingOpenAIAsyncClient(), 1);
}
public void testEmbeddingGeneration(OpenAIAsyncClient client, int expectedEmbeddingSize) {
String model = "text-embedding-ada-002";
EmbeddingGeneration<String, Float> embeddingGeneration = new OpenAITextEmbeddingGeneration(client,
model);
public void testEmbeddingGeneration(OpenAIAsyncClient client, int expectedEmbeddingSize) {
String model = "text-embedding-ada-002";
EmbeddingGeneration<String, Float> embeddingGeneration =
new OpenAITextEmbeddingGeneration(client, model);
List<String> data = new ArrayList<>();
data.add("This is just");
data.add("a test");
List<String> data = new ArrayList<>();
data.add("This is just");
data.add("a test");
embeddingGeneration
.generateEmbeddingsAsync(data)
.block()
.forEach(
embedding -> {
Assertions.assertEquals(
expectedEmbeddingSize,
embedding.getVector().size());
});
}
embeddingGeneration
.generateEmbeddingsAsync(data)
.block()
.forEach(
embedding -> {
Assertions.assertEquals(
expectedEmbeddingSize, embedding.getVector().size());
});
}
}
@@ -3,15 +3,9 @@ package com.microsoft.semantickernel.connectors.ai.openai.chatcompletion;
import static com.microsoft.semantickernel.DefaultKernelTest.mockCompletionOpenAIAsyncClient;
import java.util.ArrayList;
import com.azure.ai.openai.models.ChatCompletionsOptions;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.models.ChatCompletions;
import com.azure.ai.openai.models.ChatCompletionsOptions;
import com.microsoft.semantickernel.Kernel;
import com.microsoft.semantickernel.KernelConfig;
import com.microsoft.semantickernel.ai.AIException;
@@ -20,79 +14,88 @@ import com.microsoft.semantickernel.chatcompletion.ChatCompletion;
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
import com.microsoft.semantickernel.syntaxexamples.Example17ChatGPTTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuples;
import java.util.ArrayList;
public class OpenAIChatCompletionTest {
@Test
public void azureOpenAIChatSampleAsync() {
OpenAIAsyncClient client = mockCompletionOpenAIAsyncClient(Tuples.of("Today is", "A-RESULT"));
@Test
public void azureOpenAIChatSampleAsync() {
OpenAIAsyncClient client =
mockCompletionOpenAIAsyncClient(Tuples.of("Today is", "A-RESULT"));
String message = "Hi, I'm looking for book suggestions";
Example17ChatGPTTest.mockResponse(client, message, "1st response");
String message = "Hi, I'm looking for book suggestions";
Example17ChatGPTTest.mockResponse(client, message, "1st response");
String result = getRunExample(client, message);
Assertions.assertEquals("1st response", result);
String result = getRunExample(client, message);
Assertions.assertEquals("1st response", result);
}
private static String getRunExample(OpenAIAsyncClient client, String message) {
KernelConfig kernelConfig =
SKBuilders.kernelConfig()
.addChatCompletionService(
"gpt-3.5-turbo-0301",
kernel ->
SKBuilders.chatCompletion()
.build(client, "gpt-3.5-turbo-0301"))
.build();
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
ChatCompletion<OpenAIChatHistory> chatGPT = kernel.getService(null, ChatCompletion.class);
OpenAIChatHistory chatHistory =
chatGPT.createNewChat("You are a librarian, expert about books");
// First user message
chatHistory.addUserMessage(message);
ChatHistory.Message createdMessage = chatHistory.getLastMessage().get();
Assertions.assertEquals(ChatHistory.AuthorRoles.User, createdMessage.getAuthorRoles());
Assertions.assertEquals(message, createdMessage.getContent());
// First bot assistant message
return chatGPT.generateMessageAsync(chatHistory, null).block();
}
private static class runExample {
public final OpenAIChatHistory chatHistory;
public final String reply;
public runExample(OpenAIChatHistory chatHistory, String reply) {
this.chatHistory = chatHistory;
this.reply = reply;
}
}
private static String getRunExample(OpenAIAsyncClient client, String message) {
KernelConfig kernelConfig = SKBuilders.kernelConfig()
.addChatCompletionService(
"gpt-3.5-turbo-0301",
kernel -> SKBuilders.chatCompletion()
.build(client, "gpt-3.5-turbo-0301"))
.build();
@Test
public void emptyResponseThrowsError() {
OpenAIAsyncClient client =
mockCompletionOpenAIAsyncClient(Tuples.of("Today is", "A-RESULT"));
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
String message = "Hi, I'm looking for book suggestions";
ChatCompletion<OpenAIChatHistory> chatGPT = kernel.getService(null, ChatCompletion.class);
ChatCompletions completion = Mockito.mock(ChatCompletions.class);
Mockito.when(completion.getChoices()).thenReturn(new ArrayList<>());
OpenAIChatHistory chatHistory = chatGPT.createNewChat("You are a librarian, expert about books");
Mockito.when(
client.getChatCompletions(
Mockito.any(),
Mockito.<ChatCompletionsOptions>argThat(
msg -> {
return msg != null
&& msg.getMessages()
.get(msg.getMessages().size() - 1)
.getContent()
.equals(message);
})))
.thenReturn(Mono.just(completion));
// First user message
chatHistory.addUserMessage(message);
ChatHistory.Message createdMessage = chatHistory.getLastMessage().get();
Assertions.assertEquals(ChatHistory.AuthorRoles.User, createdMessage.getAuthorRoles());
Assertions.assertEquals(message, createdMessage.getContent());
// First bot assistant message
return chatGPT.generateMessageAsync(chatHistory, null).block();
}
private static class runExample {
public final OpenAIChatHistory chatHistory;
public final String reply;
public runExample(OpenAIChatHistory chatHistory, String reply) {
this.chatHistory = chatHistory;
this.reply = reply;
}
}
@Test
public void emptyResponseThrowsError() {
OpenAIAsyncClient client = mockCompletionOpenAIAsyncClient(Tuples.of("Today is", "A-RESULT"));
String message = "Hi, I'm looking for book suggestions";
ChatCompletions completion = Mockito.mock(ChatCompletions.class);
Mockito.when(completion.getChoices()).thenReturn(new ArrayList<>());
Mockito.when(
client.getChatCompletions(
Mockito.any(),
Mockito.<ChatCompletionsOptions>argThat(
msg -> {
return msg != null
&& msg.getMessages()
.get(msg.getMessages()
.size()
- 1)
.getContent()
.equals(message);
})))
.thenReturn(Mono.just(completion));
Assertions.assertThrows(AIException.class, () -> getRunExample(client, message));
}
Assertions.assertThrows(AIException.class, () -> getRunExample(client, message));
}
}
@@ -1,9 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.syntaxexamples;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.microsoft.semantickernel.DefaultKernelTest;
import com.microsoft.semantickernel.Kernel;
@@ -11,6 +8,9 @@ import com.microsoft.semantickernel.coreskills.TextSkill;
import com.microsoft.semantickernel.orchestration.SKContext;
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
public class Example02PipelineTest {
@@ -22,11 +22,12 @@ public class Example02PipelineTest {
// Load native skill
ReadOnlyFunctionCollection text = kernel.importSkill(new TextSkill(), null);
Mono<SKContext<?>> result = kernel.runAsync(
" i n f i n i t e s p a c e ",
text.getFunction("LStrip"),
text.getFunction("RStrip"),
text.getFunction("Uppercase"));
Mono<SKContext<?>> result =
kernel.runAsync(
" i n f i n i t e s p a c e ",
text.getFunction("LStrip"),
text.getFunction("RStrip"),
text.getFunction("Uppercase"));
Assertions.assertEquals("I N F I N I T E S P A C E", result.block().getResult());
}
@@ -1,9 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
package com.microsoft.semantickernel.syntaxexamples;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.microsoft.semantickernel.DefaultKernelTest;
import com.microsoft.semantickernel.Kernel;
@@ -13,27 +10,33 @@ import com.microsoft.semantickernel.orchestration.SKContext;
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
import com.microsoft.semantickernel.syntaxexamples.skills.StaticTextSkill;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
public class Example03VariablesTest {
@Test
public void run() {
OpenAIAsyncClient client = DefaultKernelTest.mockCompletionOpenAIAsyncClient();
Kernel kernel = DefaultKernelTest.buildKernel("model", client);
@Test
public void run() {
OpenAIAsyncClient client = DefaultKernelTest.mockCompletionOpenAIAsyncClient();
Kernel kernel = DefaultKernelTest.buildKernel("model", client);
// Load native skill
ReadOnlyFunctionCollection functionCollection = kernel.importSkill(new StaticTextSkill(), "text");
// Load native skill
ReadOnlyFunctionCollection functionCollection =
kernel.importSkill(new StaticTextSkill(), "text");
ContextVariables variables = SKBuilders.variables()
.build("Today is: ")
.writableClone()
.setVariable("day", "Monday");
ContextVariables variables =
SKBuilders.variables()
.build("Today is: ")
.writableClone()
.setVariable("day", "Monday");
Mono<SKContext<?>> result = kernel.runAsync(
variables,
functionCollection.getFunction("AppendDay"),
functionCollection.getFunction("Uppercase"));
Mono<SKContext<?>> result =
kernel.runAsync(
variables,
functionCollection.getFunction("AppendDay"),
functionCollection.getFunction("Uppercase"));
Assertions.assertEquals("TODAY IS: MONDAY", result.block().getResult());
}
Assertions.assertEquals("TODAY IS: MONDAY", result.block().getResult());
}
}
@@ -3,9 +3,6 @@ package com.microsoft.semantickernel.syntaxexamples;
import static com.microsoft.semantickernel.DefaultKernelTest.mockCompletionOpenAIAsyncClient;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.microsoft.semantickernel.Kernel;
import com.microsoft.semantickernel.KernelConfig;
@@ -15,49 +12,56 @@ import com.microsoft.semantickernel.extensions.KernelExtensions;
import com.microsoft.semantickernel.orchestration.SKContext;
import com.microsoft.semantickernel.syntaxexamples.skills.SearchEngineSkill;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuples;
public class Example04CombineLLMPromptsAndNativeCodeTest {
@Test
public void run() {
OpenAIAsyncClient client = mockCompletionOpenAIAsyncClient(
Tuples.of(
"Gran Torre Santiago is the tallest building in South America",
"A-SUMMARY"));
KernelConfig kernelConfig = SKBuilders.kernelConfig()
.addTextCompletionService(
"text-davinci-002",
kernel -> new OpenAITextCompletion(client, "text-davinci-002"))
.addTextCompletionService(
"text-davinci-003",
kernel -> new OpenAITextCompletion(client, "text-davinci-003"))
.setDefaultTextCompletionService("text-davinci-003")
.build();
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
kernel.importSkill(new SearchEngineSkill(), null);
kernel.importSkill(
"SummarizeSkill",
KernelExtensions.importSemanticSkillFromDirectory(
"../../samples/skills", "SummarizeSkill"));
// Run
String ask = "What's the tallest building in South America?";
Mono<SKContext<?>> result = kernel.runAsync(ask, kernel.getSkills().getFunction("Search", null));
Assertions.assertEquals(
@Test
public void run() {
OpenAIAsyncClient client =
mockCompletionOpenAIAsyncClient(
Tuples.of(
"Gran Torre Santiago is the tallest building in South America",
result.block().getResult());
"A-SUMMARY"));
result = kernel.runAsync(
ask,
kernel.getSkills().getFunction("Search", null),
kernel.getSkill("SummarizeSkill").getFunction("Summarize", null));
KernelConfig kernelConfig =
SKBuilders.kernelConfig()
.addTextCompletionService(
"text-davinci-002",
kernel -> new OpenAITextCompletion(client, "text-davinci-002"))
.addTextCompletionService(
"text-davinci-003",
kernel -> new OpenAITextCompletion(client, "text-davinci-003"))
.setDefaultTextCompletionService("text-davinci-003")
.build();
Assertions.assertEquals("A-SUMMARY", result.block().getResult());
}
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
kernel.importSkill(new SearchEngineSkill(), null);
kernel.importSkill(
"SummarizeSkill",
KernelExtensions.importSemanticSkillFromDirectory(
"../../samples/skills", "SummarizeSkill"));
// Run
String ask = "What's the tallest building in South America?";
Mono<SKContext<?>> result =
kernel.runAsync(ask, kernel.getSkills().getFunction("Search", null));
Assertions.assertEquals(
"Gran Torre Santiago is the tallest building in South America",
result.block().getResult());
result =
kernel.runAsync(
ask,
kernel.getSkills().getFunction("Search", null),
kernel.getSkill("SummarizeSkill").getFunction("Summarize", null));
Assertions.assertEquals("A-SUMMARY", result.block().getResult());
}
}
@@ -3,9 +3,6 @@ package com.microsoft.semantickernel.syntaxexamples;
import static com.microsoft.semantickernel.DefaultKernelTest.mockCompletionOpenAIAsyncClientMatchers;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.microsoft.semantickernel.Kernel;
import com.microsoft.semantickernel.KernelConfig;
@@ -13,46 +10,53 @@ import com.microsoft.semantickernel.builders.SKBuilders;
import com.microsoft.semantickernel.extensions.KernelExtensions;
import com.microsoft.semantickernel.planner.sequentialplanner.SequentialPlanner;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatcher;
import reactor.util.function.Tuples;
public class Example05UsingThePlannerTest {
public static SequentialPlanner getPlanner(Kernel kernel) {
kernel.importSkill(
"SummarizeSkill",
KernelExtensions.importSemanticSkillFromDirectory(
"../../samples/skills", "SummarizeSkill"));
kernel.importSkill(
"WriterSkill",
KernelExtensions.importSemanticSkillFromDirectory(
"../../samples/skills", "WriterSkill"));
public static SequentialPlanner getPlanner(Kernel kernel) {
kernel.importSkill(
"SummarizeSkill",
KernelExtensions.importSemanticSkillFromDirectory(
"../../samples/skills", "SummarizeSkill"));
kernel.importSkill(
"WriterSkill",
KernelExtensions.importSemanticSkillFromDirectory(
"../../samples/skills", "WriterSkill"));
return new SequentialPlanner(kernel, null, null);
}
return new SequentialPlanner(kernel, null, null);
}
@Test
public void run() {
ArgumentMatcher<String> matcher = prompt -> {
return prompt.contains(
"Create an XML plan step by step, to satisfy the goal given");
@Test
public void run() {
ArgumentMatcher<String> matcher =
prompt -> {
return prompt.contains(
"Create an XML plan step by step, to satisfy the goal given");
};
OpenAIAsyncClient client = mockCompletionOpenAIAsyncClientMatchers(Tuples.of(matcher, "A-PLAN"));
OpenAIAsyncClient client =
mockCompletionOpenAIAsyncClientMatchers(Tuples.of(matcher, "A-PLAN"));
KernelConfig config = SKBuilders.kernelConfig()
.addTextCompletionService(
"davinci",
kernel -> SKBuilders.textCompletionService()
.build(client, "text-davinci-003"))
.build();
KernelConfig config =
SKBuilders.kernelConfig()
.addTextCompletionService(
"davinci",
kernel ->
SKBuilders.textCompletionService()
.build(client, "text-davinci-003"))
.build();
Kernel kernel = SKBuilders.kernel().setKernelConfig(config).build();
Kernel kernel = SKBuilders.kernel().setKernelConfig(config).build();
SequentialPlanner planner = getPlanner(kernel);
System.out.println(
planner.createPlanAsync(
"Write a poem about John Doe, then translate it into Italian.")
.block()
.getResult());
}
SequentialPlanner planner = getPlanner(kernel);
System.out.println(
planner.createPlanAsync(
"Write a poem about John Doe, then translate it into Italian.")
.block()
.getResult());
}
}
@@ -3,11 +3,6 @@ package com.microsoft.semantickernel.syntaxexamples;
import static com.microsoft.semantickernel.DefaultKernelTest.mockCompletionOpenAIAsyncClient;
import java.util.ArrayList;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.microsoft.semantickernel.Kernel;
import com.microsoft.semantickernel.KernelConfig;
@@ -19,66 +14,77 @@ import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
import com.microsoft.semantickernel.templateengine.PromptTemplateEngine;
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuples;
import java.util.ArrayList;
public class Example06TemplateLanguageTest {
@Test
public void run() {
OpenAIAsyncClient client = mockCompletionOpenAIAsyncClient(Tuples.of("Today is", "A-RESULT"));
@Test
public void run() {
OpenAIAsyncClient client =
mockCompletionOpenAIAsyncClient(Tuples.of("Today is", "A-RESULT"));
KernelConfig kernelConfig = SKBuilders.kernelConfig()
.addTextCompletionService(
"text-davinci-003",
kernel -> SKBuilders.textCompletionService()
.build(client, "text-davinci-003"))
.addTextEmbeddingsGenerationService(
"text-embedding-ada-002",
kernel -> SKBuilders.textEmbeddingGenerationService()
.build(client, "text-embedding-ada-002"))
.build();
KernelConfig kernelConfig =
SKBuilders.kernelConfig()
.addTextCompletionService(
"text-davinci-003",
kernel ->
SKBuilders.textCompletionService()
.build(client, "text-davinci-003"))
.addTextEmbeddingsGenerationService(
"text-embedding-ada-002",
kernel ->
SKBuilders.textEmbeddingGenerationService()
.build(client, "text-embedding-ada-002"))
.build();
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
// Load native skill into the kernel skill collection, sharing its functions
// with prompt
// templates
// Functions loaded here are available as "time.*"
kernel.importSkill(new TimeSkill(), "time");
// Load native skill into the kernel skill collection, sharing its functions
// with prompt
// templates
// Functions loaded here are available as "time.*"
kernel.importSkill(new TimeSkill(), "time");
// Semantic Function invoking time.Date and time.Time native functions
String functionDefinition = "\n"
+ "Today is: {{time.Date}}\n"
+ "Current time is: {{time.Time}}\n"
+ "\n"
+ "Answer to the following questions using JSON syntax, including the data"
+ " used.\n"
+ "Is it morning, afternoon, evening, or night"
+ " (morning/afternoon/evening/night)?\n"
+ "Is it weekend time (weekend/not weekend)?";
// Semantic Function invoking time.Date and time.Time native functions
String functionDefinition =
"\n"
+ "Today is: {{time.Date}}\n"
+ "Current time is: {{time.Time}}\n"
+ "\n"
+ "Answer to the following questions using JSON syntax, including the data"
+ " used.\n"
+ "Is it morning, afternoon, evening, or night"
+ " (morning/afternoon/evening/night)?\n"
+ "Is it weekend time (weekend/not weekend)?";
PromptTemplate promptRenderer = SKBuilders.promptTemplate().build(functionDefinition, null);
PromptTemplate promptRenderer = SKBuilders.promptTemplate().build(functionDefinition, null);
SKContext skContext = SKBuilders.context().build(kernel.getSkills());
SKContext skContext = SKBuilders.context().build(kernel.getSkills());
PromptTemplateEngine promptTemplateEngine = SKBuilders.promptTemplateEngine().build();
PromptTemplateEngine promptTemplateEngine = SKBuilders.promptTemplateEngine().build();
Mono<String> renderedPrompt = promptRenderer.renderAsync(skContext, promptTemplateEngine);
Mono<String> renderedPrompt = promptRenderer.renderAsync(skContext, promptTemplateEngine);
// Check that it has been rendered
Assertions.assertTrue(!renderedPrompt.block().contains("time.Date"));
// Check that it has been rendered
Assertions.assertTrue(!renderedPrompt.block().contains("time.Date"));
// Run the prompt / semantic function
CompletionSKFunction kindOfDay = kernel.getSemanticFunctionBuilder()
.createFunction(
functionDefinition,
null,
null,
null,
new PromptTemplateConfig.CompletionConfig(
0, 0, 0, 0, 256, new ArrayList<>()));
// Run the prompt / semantic function
CompletionSKFunction kindOfDay =
kernel.getSemanticFunctionBuilder()
.createFunction(
functionDefinition,
null,
null,
null,
new PromptTemplateConfig.CompletionConfig(
0, 0, 0, 0, 256, new ArrayList<>()));
Assertions.assertEquals("A-RESULT", kindOfDay.invokeAsync("").block().getResult());
}
Assertions.assertEquals("A-RESULT", kindOfDay.invokeAsync("").block().getResult());
}
}
@@ -3,12 +3,6 @@ package com.microsoft.semantickernel.syntaxexamples;
import static com.microsoft.semantickernel.DefaultKernelTest.mockCompletionOpenAIAsyncClient;
import java.util.Arrays;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import com.azure.ai.openai.OpenAIAsyncClient;
import com.azure.ai.openai.models.ChatChoice;
import com.azure.ai.openai.models.ChatCompletions;
@@ -20,80 +14,89 @@ import com.microsoft.semantickernel.chatcompletion.ChatCompletion;
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
import com.microsoft.semantickernel.connectors.ai.openai.chatcompletion.OpenAIChatHistory;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import reactor.core.publisher.Mono;
import reactor.util.function.Tuples;
import java.util.Arrays;
public class Example17ChatGPTTest {
@Test
public void azureOpenAIChatSampleAsync() {
@Test
public void azureOpenAIChatSampleAsync() {
OpenAIAsyncClient client = mockCompletionOpenAIAsyncClient(Tuples.of("Today is", "A-RESULT"));
OpenAIAsyncClient client =
mockCompletionOpenAIAsyncClient(Tuples.of("Today is", "A-RESULT"));
String message = "Hi, I'm looking for book suggestions";
String secondMessage = "I love history and philosophy, I'd like to learn something new about Greece, any"
+ " suggestion?";
String message = "Hi, I'm looking for book suggestions";
String secondMessage =
"I love history and philosophy, I'd like to learn something new about Greece, any"
+ " suggestion?";
mockResponse(client, message, "1st response");
mockResponse(client, secondMessage, "2nd response");
mockResponse(client, message, "1st response");
mockResponse(client, secondMessage, "2nd response");
KernelConfig kernelConfig = SKBuilders.kernelConfig()
.addChatCompletionService(
"gpt-3.5-turbo-0301",
kernel -> SKBuilders.chatCompletion()
.build(client, "gpt-3.5-turbo-0301"))
.build();
KernelConfig kernelConfig =
SKBuilders.kernelConfig()
.addChatCompletionService(
"gpt-3.5-turbo-0301",
kernel ->
SKBuilders.chatCompletion()
.build(client, "gpt-3.5-turbo-0301"))
.build();
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
Kernel kernel = SKBuilders.kernel().setKernelConfig(kernelConfig).build();
ChatCompletion<OpenAIChatHistory> chatGPT = kernel.getService(null, ChatCompletion.class);
ChatCompletion<OpenAIChatHistory> chatGPT = kernel.getService(null, ChatCompletion.class);
OpenAIChatHistory chatHistory = chatGPT.createNewChat("You are a librarian, expert about books");
OpenAIChatHistory chatHistory =
chatGPT.createNewChat("You are a librarian, expert about books");
// First user message
chatHistory.addUserMessage(message);
ChatHistory.Message createdMessage = chatHistory.getMessages()
.get(chatHistory.getMessages().size() - 1);
Assertions.assertEquals(ChatHistory.AuthorRoles.User, createdMessage.getAuthorRoles());
Assertions.assertEquals(message, createdMessage.getContent());
// First user message
chatHistory.addUserMessage(message);
ChatHistory.Message createdMessage =
chatHistory.getMessages().get(chatHistory.getMessages().size() - 1);
Assertions.assertEquals(ChatHistory.AuthorRoles.User, createdMessage.getAuthorRoles());
Assertions.assertEquals(message, createdMessage.getContent());
// First bot assistant message
String reply = chatGPT.generateMessageAsync(chatHistory, null).block();
Assertions.assertEquals("1st response", reply);
chatHistory.addAssistantMessage(reply);
// First bot assistant message
String reply = chatGPT.generateMessageAsync(chatHistory, null).block();
Assertions.assertEquals("1st response", reply);
chatHistory.addAssistantMessage(reply);
// Second user message
chatHistory.addUserMessage(secondMessage);
// Second user message
chatHistory.addUserMessage(secondMessage);
// Second bot assistant message
reply = chatGPT.generateMessageAsync(chatHistory, null).block();
Assertions.assertEquals("2nd response", reply);
}
// Second bot assistant message
reply = chatGPT.generateMessageAsync(chatHistory, null).block();
Assertions.assertEquals("2nd response", reply);
}
public static void mockResponse(OpenAIAsyncClient client, String message, String response) {
ChatMessage chatMessage = Mockito.mock(ChatMessage.class);
ChatChoice chatChoice = Mockito.mock(ChatChoice.class);
ChatCompletions completion = Mockito.mock(ChatCompletions.class);
public static void mockResponse(OpenAIAsyncClient client, String message, String response) {
ChatMessage chatMessage = Mockito.mock(ChatMessage.class);
ChatChoice chatChoice = Mockito.mock(ChatChoice.class);
ChatCompletions completion = Mockito.mock(ChatCompletions.class);
Mockito.when(completion.getChoices()).thenReturn(Arrays.asList(chatChoice));
Mockito.when(completion.getChoices()).thenReturn(Arrays.asList(chatChoice));
Mockito.when(chatChoice.getMessage()).thenReturn(chatMessage);
Mockito.when(chatChoice.getMessage()).thenReturn(chatMessage);
Mockito.when(chatMessage.getContent()).thenReturn(response);
Mockito.when(chatMessage.getContent()).thenReturn(response);
Mockito.when(
client.getChatCompletions(
Mockito.any(),
Mockito.argThat(
msg -> {
return msg != null
&& msg.getMessages()
.get(msg.getMessages()
.size()
- 1)
.getContent()
.equals(message);
})))
.thenReturn(Mono.just(completion));
}
Mockito.when(
client.getChatCompletions(
Mockito.any(),
Mockito.argThat(
msg -> {
return msg != null
&& msg.getMessages()
.get(msg.getMessages().size() - 1)
.getContent()
.equals(message);
})))
.thenReturn(Mono.just(completion));
}
}