mirror of
https://github.com/microsoft/semantic-kernel.git
synced 2026-10-12 02:19:06 +00:00
Java: merge dsgrieve/java-v1-api into java-v1 (#4405)
Work on 01, 02, 03, 04 examples of the SK-v1 API --------- Co-authored-by: John Oliver <[email protected]>
This commit is contained in:
co-authored by
John Oliver
parent
1d9a1b47cf
commit
da2ac37b4b
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"java.compile.nullAnalysis.mode": "automatic"
|
||||
}
|
||||
@@ -15,6 +15,10 @@
|
||||
<description>Azure OpenAI services for Semantic Kernel</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.azure</groupId>
|
||||
<artifactId>azure-ai-openai</artifactId>
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
package com.microsoft.semantickernel.aiservices.azureopenai;
|
||||
|
||||
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.Kernel;
|
||||
import com.microsoft.semantickernel.exceptions.AIException;
|
||||
import com.microsoft.semantickernel.orchestration.PromptExecutionSettings;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable;
|
||||
import com.microsoft.semantickernel.textcompletion.StreamingTextContent;
|
||||
import com.microsoft.semantickernel.textcompletion.TextContent;
|
||||
import com.microsoft.semantickernel.textcompletion.TextGenerationService;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class AzureOpenAITextGenerationService implements TextGenerationService {
|
||||
|
||||
private final OpenAIAsyncClient client;
|
||||
private final Map<String, ContextVariable<?>> attributes;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new <see cref="AzureOpenAITextGenerationService"/> client instance supporting AAD auth
|
||||
/// </summary>
|
||||
/// <param name="deploymentName">Azure OpenAI deployment name, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource</param>
|
||||
/// <param name="endpoint">Azure OpenAI deployment URL, see https://learn.microsoft.com/azure/cognitive-services/openai/quickstart</param>
|
||||
/// <param name="credential">Token credentials, e.g. DefaultAzureCredential, ManagedIdentityCredential, EnvironmentCredential, etc.</param>
|
||||
/// <param name="modelId">Azure OpenAI model id, see https://learn.microsoft.com/azure/cognitive-services/openai/how-to/create-resource</param>
|
||||
/// <param name="httpClient">Custom <see cref="HttpClient"/> for HTTP requests.</param>
|
||||
/// <param name="loggerFactory">The <see cref="ILoggerFactory"/> to use for logging. If null, no logging will be performed.</param>
|
||||
public AzureOpenAITextGenerationService(
|
||||
OpenAIAsyncClient client,
|
||||
String modelId) {
|
||||
this.client = client;
|
||||
attributes = new HashMap<>();
|
||||
attributes.put(MODEL_ID_KEY, ContextVariable.of(modelId));
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ContextVariable<?>> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<List<TextContent>> getTextContentsAsync(String prompt,
|
||||
@Nullable PromptExecutionSettings executionSettings, @Nullable Kernel kernel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<StreamingTextContent> getStreamingTextContentsAsync(
|
||||
String prompt,
|
||||
@Nullable PromptExecutionSettings executionSettings,
|
||||
@Nullable Kernel kernel) {
|
||||
return this
|
||||
.internalCompleteTextAsync(prompt, executionSettings)
|
||||
.flatMapMany(it -> {
|
||||
return Flux.fromStream(it.stream())
|
||||
.map(TextContent::new)
|
||||
.map(StreamingTextContent::new);
|
||||
});
|
||||
}
|
||||
|
||||
protected Mono<List<String>> internalCompleteTextAsync(
|
||||
String text,
|
||||
PromptExecutionSettings requestSettings) {
|
||||
|
||||
CompletionsOptions completionsOptions = getCompletionsOptions(text, requestSettings);
|
||||
|
||||
return client
|
||||
.getCompletions(getModelId(), completionsOptions)
|
||||
.flatMapIterable(Completions::getChoices)
|
||||
.mapNotNull(Choice::getText)
|
||||
.collectList();
|
||||
}
|
||||
|
||||
private CompletionsOptions getCompletionsOptions(
|
||||
String text, PromptExecutionSettings requestSettings) {
|
||||
if (requestSettings == null) {
|
||||
return new CompletionsOptions(Collections.singletonList(text))
|
||||
.setMaxTokens(PromptExecutionSettings.DEFAULT_MAX_TOKENS);
|
||||
}
|
||||
if (requestSettings.getMaxTokens() < 1) {
|
||||
throw new AIException(AIException.ErrorCodes.INVALID_REQUEST, "Max tokens must be >0");
|
||||
}
|
||||
|
||||
CompletionsOptions options =
|
||||
new CompletionsOptions(Collections.singletonList(text))
|
||||
.setMaxTokens(requestSettings.getMaxTokens())
|
||||
.setTemperature(requestSettings.getTemperature())
|
||||
.setTopP(requestSettings.getTopP())
|
||||
.setFrequencyPenalty(requestSettings.getFrequencyPenalty())
|
||||
.setPresencePenalty(requestSettings.getPresencePenalty())
|
||||
.setModel(getModelId())
|
||||
.setUser(requestSettings.getUser())
|
||||
.setBestOf(requestSettings.getBestOf())
|
||||
.setLogitBias(new HashMap<>());
|
||||
/*
|
||||
if (requestSettings instanceof ChatRequestSettings) {
|
||||
options = options.setStop(requestSettings.getStopSequences());
|
||||
}
|
||||
|
||||
*/
|
||||
return options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for a ChatCompletionService that uses Azure AI.
|
||||
*/
|
||||
public static class Builder {
|
||||
|
||||
private String modelId;
|
||||
private OpenAIAsyncClient client;
|
||||
|
||||
public Builder withModelId(String modelId) {
|
||||
this.modelId = modelId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withOpenAIAsyncClient(OpenAIAsyncClient client) {
|
||||
this.client = client;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AzureOpenAITextGenerationService build() {
|
||||
return new AzureOpenAITextGenerationService(
|
||||
this.client,
|
||||
this.modelId
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+320
@@ -0,0 +1,320 @@
|
||||
package com.microsoft.semantickernel.aiservices.azureopenai.chatcompletion;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.xml.stream.XMLEventReader;
|
||||
import javax.xml.stream.XMLInputFactory;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.azure.ai.openai.OpenAIClientBuilder;
|
||||
import com.azure.ai.openai.models.ChatChoice;
|
||||
import com.azure.ai.openai.models.ChatCompletions;
|
||||
import com.azure.ai.openai.models.ChatCompletionsOptions;
|
||||
import com.azure.ai.openai.models.ChatRequestAssistantMessage;
|
||||
import com.azure.ai.openai.models.ChatRequestMessage;
|
||||
import com.azure.ai.openai.models.ChatRequestSystemMessage;
|
||||
import com.azure.ai.openai.models.ChatRequestToolMessage;
|
||||
import com.azure.ai.openai.models.ChatRequestUserMessage;
|
||||
import com.azure.ai.openai.models.ChatResponseMessage;
|
||||
import com.azure.ai.openai.models.ChatRole;
|
||||
import com.azure.core.credential.KeyCredential;
|
||||
import com.azure.core.credential.TokenCredential;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.chatcompletion.AuthorRole;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletionService;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatMessageContent;
|
||||
import com.microsoft.semantickernel.chatcompletion.StreamingChatMessageContent;
|
||||
import com.microsoft.semantickernel.orchestration.PromptExecutionSettings;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class AzureOpenAIChatCompletion implements com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AzureOpenAIChatCompletion.class);
|
||||
|
||||
private final OpenAIAsyncClient client;
|
||||
private final Map<String, ContextVariable<?>> attributes;
|
||||
|
||||
public AzureOpenAIChatCompletion(OpenAIAsyncClient client, String modelId) {
|
||||
this.client = client;
|
||||
this.attributes = new HashMap<>();
|
||||
attributes.put(MODEL_ID_KEY, ContextVariable.of(modelId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ContextVariable<?>> getAttributes() {
|
||||
return attributes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<List<ChatMessageContent>> getChatMessageContentsAsync(ChatHistory chatHistory,
|
||||
@Nullable PromptExecutionSettings promptExecutionSettings, @Nullable Kernel kernel) {
|
||||
|
||||
List<ChatRequestMessage> chatRequestMessages = getChatRequestMessages(chatHistory);
|
||||
return internalChatMessageContentsAsync(chatRequestMessages, promptExecutionSettings);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<StreamingChatMessageContent> getStreamingChatMessageContentsAsync(ChatHistory chatHistory,
|
||||
PromptExecutionSettings promptExecutionSettings, Kernel kernel)
|
||||
{
|
||||
List<ChatRequestMessage> chatRequestMessages = getChatRequestMessages(chatHistory);
|
||||
return internalStreamingChatMessageContentsAsync(chatRequestMessages, promptExecutionSettings);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<List<ChatMessageContent>> getChatMessageContentsAsync(String prompt,
|
||||
PromptExecutionSettings promptExecutionSettings, Kernel kernel) {
|
||||
List<ChatRequestMessage> chatRequestMessages = getChatRequestMessages(prompt);
|
||||
return internalChatMessageContentsAsync(chatRequestMessages, promptExecutionSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<StreamingChatMessageContent> getStreamingChatMessageContentsAsync(String prompt,
|
||||
PromptExecutionSettings promptExecutionSettings, Kernel kernel) {
|
||||
List<ChatRequestMessage> chatRequestMessages = getChatRequestMessages(prompt);
|
||||
return internalStreamingChatMessageContentsAsync(chatRequestMessages, promptExecutionSettings);
|
||||
}
|
||||
|
||||
private Flux<StreamingChatMessageContent> internalStreamingChatMessageContentsAsync(
|
||||
List<ChatRequestMessage> chatRequestMessages,
|
||||
PromptExecutionSettings promptExecutionSettings)
|
||||
{
|
||||
ChatCompletionsOptions options = getCompletionsOptions(this, chatRequestMessages, promptExecutionSettings);
|
||||
return client
|
||||
.getChatCompletionsStream(getModelId(), options)
|
||||
.filter(chatCompletion -> chatCompletion != null)
|
||||
.map(ChatCompletions::getChoices)
|
||||
.filter(choices -> choices != null && !choices.isEmpty())
|
||||
.collect(StringBuffer::new, (sb, choices) -> {
|
||||
choices.stream()
|
||||
.map(choice -> choice.getDelta())
|
||||
.filter(delta -> delta != null && delta.getContent() != null)
|
||||
.forEach(delta -> sb.append(delta.getContent()));
|
||||
})
|
||||
.map(sb -> {
|
||||
return sb.toString();
|
||||
})
|
||||
.map(content -> new StreamingChatMessageContent(AuthorRole.ASSISTANT, content))
|
||||
.flux();
|
||||
}
|
||||
|
||||
private Mono<List<ChatMessageContent>> internalChatMessageContentsAsync(
|
||||
List<ChatRequestMessage> chatRequestMessages,
|
||||
PromptExecutionSettings promptExecutionSettings)
|
||||
{
|
||||
ChatCompletionsOptions options = getCompletionsOptions(this, chatRequestMessages, promptExecutionSettings);
|
||||
return client
|
||||
.getChatCompletions(getModelId(), options)
|
||||
.flatMap(chatCompletions -> Mono.just(toChatMessageContents(chatCompletions)));
|
||||
}
|
||||
|
||||
private static ChatCompletionsOptions getCompletionsOptions(
|
||||
ChatCompletionService chatCompletionService,
|
||||
List<ChatRequestMessage> chatRequestMessages,
|
||||
PromptExecutionSettings promptExecutionSettings)
|
||||
{
|
||||
ChatCompletionsOptions options = new ChatCompletionsOptions(chatRequestMessages)
|
||||
.setModel(chatCompletionService.getModelId());
|
||||
|
||||
if (promptExecutionSettings == null) {
|
||||
return options;
|
||||
}
|
||||
|
||||
options
|
||||
.setTemperature(promptExecutionSettings.getTemperature())
|
||||
.setTopP(promptExecutionSettings.getTopP())
|
||||
.setPresencePenalty(promptExecutionSettings.getPresencePenalty())
|
||||
.setFrequencyPenalty(promptExecutionSettings.getFrequencyPenalty())
|
||||
.setPresencePenalty(promptExecutionSettings.getPresencePenalty())
|
||||
.setMaxTokens(promptExecutionSettings.getMaxTokens())
|
||||
// Azure OpenAI WithData API does not allow to send empty array of stop sequences
|
||||
// Gives back "Validation error at #/stop/str: Input should be a valid string\nValidation error at #/stop/list[str]: List should have at least 1 item after validation, not 0"
|
||||
.setStop(promptExecutionSettings.getStopSequences() == null || promptExecutionSettings.getStopSequences().isEmpty() ? null : promptExecutionSettings.getStopSequences())
|
||||
.setUser(promptExecutionSettings.getUser())
|
||||
.setLogitBias(new HashMap<>());
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
private static List<ChatRequestMessage> getChatRequestMessages(ChatHistory chatHistory)
|
||||
{
|
||||
List<ChatMessageContent> messages = chatHistory.getMessages();
|
||||
if (messages == null || messages.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return messages.stream()
|
||||
.map(message -> {
|
||||
AuthorRole authorRole = message.getAuthorRole();
|
||||
String content = message.getContent();
|
||||
return getChatRequestMessage(authorRole, content);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static List<ChatRequestMessage> getChatRequestMessages(String prompt)
|
||||
{
|
||||
List<ChatRequestMessage> messages = new ArrayList<>();
|
||||
try (InputStream is = new ByteArrayInputStream(prompt.getBytes())) {
|
||||
XMLInputFactory factory = XMLInputFactory.newFactory();
|
||||
XMLEventReader reader = factory.createXMLEventReader(is);
|
||||
while(reader.hasNext()) {
|
||||
XMLEvent event = reader.nextEvent();
|
||||
if (event.isStartElement()) {
|
||||
String name = event.asStartElement().getName().getLocalPart();
|
||||
if (name.equals("message")) {
|
||||
String role = event.asStartElement().getAttributeByName(javax.xml.namespace.QName.valueOf("role")).getValue();
|
||||
String content = reader.getElementText();
|
||||
messages.add(getChatRequestMessage(AuthorRole.valueOf(role.toUpperCase()), content));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException | XMLStreamException | IllegalArgumentException e) {
|
||||
LOGGER.error("Error parsing prompt", e);
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
private static ChatRequestMessage getChatRequestMessage(
|
||||
AuthorRole authorRole,
|
||||
String content)
|
||||
{
|
||||
|
||||
if (authorRole != null) {
|
||||
switch(authorRole) {
|
||||
case ASSISTANT:
|
||||
return new ChatRequestAssistantMessage(content);
|
||||
case SYSTEM:
|
||||
return new ChatRequestSystemMessage(content);
|
||||
case USER:
|
||||
return new ChatRequestUserMessage(content);
|
||||
case TOOL:
|
||||
return new ChatRequestToolMessage(content, null);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown author role: " + authorRole);
|
||||
}
|
||||
|
||||
private static List<ChatMessageContent> toChatMessageContents(ChatCompletions chatCompletions) {
|
||||
|
||||
if (chatCompletions == null || chatCompletions.getChoices() == null || chatCompletions.getChoices().isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return chatCompletions.getChoices().stream()
|
||||
.map(ChatChoice::getMessage)
|
||||
.map(AzureOpenAIChatCompletion::toChatMessageContent)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static ChatMessageContent toChatMessageContent(ChatResponseMessage message) {
|
||||
return new ChatMessageContent(toAuthorRole(message.getRole()), message.getContent());
|
||||
}
|
||||
|
||||
private static AuthorRole toAuthorRole(ChatRole chatRole) {
|
||||
if (chatRole == null) {
|
||||
return null;
|
||||
}
|
||||
if(chatRole == ChatRole.ASSISTANT) {
|
||||
return AuthorRole.ASSISTANT;
|
||||
}
|
||||
if(chatRole == ChatRole.ASSISTANT) {
|
||||
return AuthorRole.SYSTEM;
|
||||
}
|
||||
if(chatRole == ChatRole.ASSISTANT) {
|
||||
return AuthorRole.USER;
|
||||
}
|
||||
if(chatRole == ChatRole.ASSISTANT) {
|
||||
return AuthorRole.TOOL;
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown chat role: " + chatRole);
|
||||
}
|
||||
|
||||
public static class Builder implements com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion.Builder {
|
||||
|
||||
private OpenAIAsyncClient client;
|
||||
private String modelId;
|
||||
private String apiKey;
|
||||
private String endpoint;
|
||||
private TokenCredential tokenCredential;
|
||||
|
||||
@Override
|
||||
public AzureOpenAIChatCompletion build() {
|
||||
|
||||
OpenAIAsyncClient asyncClient;
|
||||
if ((asyncClient = this.client) == null) {
|
||||
if (tokenCredential != null) {
|
||||
Objects.requireNonNull(endpoint, "Endpoint must be set");
|
||||
asyncClient = new OpenAIClientBuilder()
|
||||
.credential(tokenCredential)
|
||||
.endpoint(endpoint)
|
||||
.buildAsyncClient();
|
||||
} else {
|
||||
Objects.requireNonNull(apiKey, "API key must be set");
|
||||
Objects.requireNonNull(endpoint, "Endpoint must be set");
|
||||
asyncClient = new OpenAIClientBuilder()
|
||||
.credential(new KeyCredential(apiKey))
|
||||
.endpoint(endpoint)
|
||||
.buildAsyncClient();
|
||||
}
|
||||
}
|
||||
Objects.requireNonNull(modelId, "Model ID must be set");
|
||||
return new AzureOpenAIChatCompletion(asyncClient, modelId);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion.Builder withModelId(
|
||||
String modelId) {
|
||||
this.modelId = modelId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion.Builder withOpenAIAsyncClient(
|
||||
OpenAIAsyncClient openAIClient) {
|
||||
this.client = openAIClient;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion.Builder withApiKey(
|
||||
String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion.Builder withEndpoint(
|
||||
String endpoint) {
|
||||
this.endpoint = endpoint;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion.Builder withTokenCredential(
|
||||
TokenCredential tokenCredential) {
|
||||
this.tokenCredential = tokenCredential;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.microsoft.semantickernel.aiservices.azureopenai.chatcompletion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public interface AzureOpenAIChatResponse {
|
||||
|
||||
interface Usage {
|
||||
|
||||
@JsonProperty("prompt_tokens")
|
||||
int getPromptTokens();
|
||||
|
||||
@JsonProperty("completion_tokens")
|
||||
int getCompletionTokens();
|
||||
|
||||
@JsonProperty("total_tokens")
|
||||
int getTotalTokens();
|
||||
}
|
||||
|
||||
interface Choice {
|
||||
|
||||
@JsonProperty("message")
|
||||
Message getMessage();
|
||||
|
||||
@JsonProperty("finish_details")
|
||||
FinishDetails getFinishDetails();
|
||||
|
||||
@JsonProperty("index")
|
||||
int getIndex();
|
||||
}
|
||||
|
||||
interface Message {
|
||||
|
||||
@JsonProperty("role")
|
||||
String getRole();
|
||||
|
||||
@JsonProperty("content")
|
||||
String getContent();
|
||||
}
|
||||
|
||||
interface FinishDetails {
|
||||
|
||||
@JsonProperty("type")
|
||||
String getType();
|
||||
}
|
||||
|
||||
@JsonProperty("id")
|
||||
String getId();
|
||||
|
||||
@JsonProperty("object")
|
||||
String getObject();
|
||||
|
||||
@JsonProperty("created")
|
||||
Long getCreated();
|
||||
|
||||
@JsonProperty("model")
|
||||
String getModel();
|
||||
|
||||
@JsonProperty("Usage")
|
||||
List<Usage> getUsage();
|
||||
|
||||
@JsonProperty("choices")
|
||||
List<Choice> getChoices();
|
||||
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
com.microsoft.semantickernel.aiservices.azureopenai.chatcompletion.AzureOpenAIChatCompletion$Builder
|
||||
-107
@@ -1,107 +0,0 @@
|
||||
package com.microsoft.semantickernel.aiservices.openai;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.azure.ai.openai.models.ChatCompletions;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletion;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatRequestSettings;
|
||||
import com.microsoft.semantickernel.orchestration.FunctionResult;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionRequestSettings;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionType;
|
||||
import com.microsoft.semantickernel.aiservices.AIService;
|
||||
import com.microsoft.semantickernel.aiservices.responsetypes.BinaryFile;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class OpenAIChatCompletion implements AIService, ChatCompletion<ChatHistory> {
|
||||
|
||||
public OpenAIChatCompletion(String modelId, String apiKey) {}
|
||||
|
||||
@Override
|
||||
public Mono<List<String>> completeAsync(@Nonnull String text, @Nonnull CompletionRequestSettings requestSettings) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'completeAsync'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<String> completeStreamAsync(@Nonnull String text, @Nonnull CompletionRequestSettings requestSettings) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'completeStreamAsync'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletionType defaultCompletionType() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'defaultCompletionType'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> generateMessageAsync(ChatHistory chat, @Nullable ChatRequestSettings requestSettings) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'generateMessageAsync'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatHistory createNewChat(String instructions) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'createNewChat'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChatHistory createNewChat() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'createNewChat'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<String> generateMessageStream(ChatHistory chatHistory, @Nullable ChatRequestSettings requestSettings) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'generateMessageStream'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<ChatCompletions> getStreamingChatCompletionsAsync(ChatHistory chat,
|
||||
ChatRequestSettings requestSettings) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getStreamingChatCompletionsAsync'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModelId() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getModelId'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getOutputTypes() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getOutputTypes'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getCapabilities() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getCapabilities'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<FunctionResult> getModelResultAsync(Kernel kernel, String pluginName, String name, String prompt,
|
||||
Map<Object, BinaryFile> files) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getModelResultAsync'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<FunctionResult> getModelStreamingResultAsync(Kernel kernel, String pluginName, String name,
|
||||
String prompt, Map<Object, BinaryFile> files) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getModelStreamingResultAsync'");
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
package com.microsoft.semantickernel.aiservices.openai.chatcompletion;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.azure.ai.openai.OpenAIClientBuilder;
|
||||
import com.azure.core.credential.KeyCredential;
|
||||
import com.azure.core.credential.TokenCredential;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatMessageContent;
|
||||
import com.microsoft.semantickernel.chatcompletion.StreamingChatMessageContent;
|
||||
import com.microsoft.semantickernel.orchestration.PromptExecutionSettings;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class OpenAIChatCompletion implements com.microsoft.semantickernel.chatcompletion.OpenAIChatCompletion {
|
||||
|
||||
private final OpenAIAsyncClient client;
|
||||
private final String modelId;
|
||||
|
||||
public OpenAIChatCompletion(OpenAIAsyncClient client, String modelId) {
|
||||
this.client = client;
|
||||
this.modelId = modelId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, ContextVariable<?>> getAttributes() {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getAttributes'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<List<ChatMessageContent>> getChatMessageContentsAsync(ChatHistory chatHistory,
|
||||
PromptExecutionSettings promptExecutionSettings, Kernel kernel) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getChatMessageContentsAsync'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<StreamingChatMessageContent> getStreamingChatMessageContentsAsync(ChatHistory chatHistory,
|
||||
PromptExecutionSettings promptExecutionSettings, Kernel kernel) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getStreamingChatMessageContentsAsync'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<List<ChatMessageContent>> getChatMessageContentsAsync(String prompt,
|
||||
PromptExecutionSettings promptExecutionSettings, Kernel kernel) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getStreamingChatMessageContentsAsync'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<StreamingChatMessageContent> getStreamingChatMessageContentsAsync(String prompt,
|
||||
PromptExecutionSettings promptExecutionSettings, Kernel kernel) {
|
||||
// TODO Auto-generated method stub
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getStreamingChatMessageContentsAsync'");
|
||||
}
|
||||
|
||||
public static class Builder implements com.microsoft.semantickernel.chatcompletion.OpenAIChatCompletion.Builder {
|
||||
|
||||
private OpenAIAsyncClient client;
|
||||
private String modelId;
|
||||
private String apiKey;
|
||||
private String organization;
|
||||
private TokenCredential tokenCredential;
|
||||
|
||||
@Override
|
||||
public OpenAIChatCompletion build() {
|
||||
OpenAIAsyncClient asyncClient;
|
||||
if ((asyncClient = this.client) == null) {
|
||||
if (tokenCredential != null) {
|
||||
asyncClient = new OpenAIClientBuilder()
|
||||
.credential(tokenCredential)
|
||||
.buildAsyncClient();
|
||||
} else {
|
||||
Objects.requireNonNull(apiKey, "API key must be set");
|
||||
asyncClient = new OpenAIClientBuilder()
|
||||
.credential(new KeyCredential(apiKey))
|
||||
.buildAsyncClient();
|
||||
}
|
||||
}
|
||||
Objects.requireNonNull(modelId, "Model ID must be set");
|
||||
return new OpenAIChatCompletion(asyncClient, modelId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.OpenAIChatCompletion.Builder withOpenAIAsyncClient(
|
||||
OpenAIAsyncClient openAIClient) {
|
||||
this.client = openAIClient;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.OpenAIChatCompletion.Builder withApiKey(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.OpenAIChatCompletion.Builder withOrganization(
|
||||
String organization) {
|
||||
this.organization = organization;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.OpenAIChatCompletion.Builder withTokenCredential(
|
||||
TokenCredential tokenCredential) {
|
||||
this.tokenCredential = tokenCredential;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public com.microsoft.semantickernel.chatcompletion.OpenAIChatCompletion.Builder withModelId(
|
||||
String modelId) {
|
||||
this.modelId = modelId;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.microsoft.semantickernel.aiservices.openai;
|
||||
package com.microsoft.semantickernel.aiservices.openai.chatcompletion;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
com.microsoft.semantickernel.aiservices.openai.chatcompletion.OpenAIChatCompletion$Builder
|
||||
@@ -4,8 +4,8 @@ import com.azure.ai.openai.OpenAIClientBuilder;
|
||||
import com.azure.core.credential.AzureKeyCredential;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionKernelFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -97,17 +97,17 @@ public class InlineFunctionExample {
|
||||
.buildAsyncClient();
|
||||
|
||||
TextCompletion textCompletion =
|
||||
SKBuilders.textCompletion().withOpenAIClient(client).withModelId(MODEL).build();
|
||||
SKBuilders.textCompletion().withOpenAIAsyncClient(client).withModelId(MODEL).build();
|
||||
String prompt = "{{$input}}\n" + "Summarize the content above.";
|
||||
|
||||
Kernel kernel = SKBuilders.kernel().withDefaultAIService(textCompletion).build();
|
||||
|
||||
CompletionSKFunction summarize =
|
||||
CompletionKernelFunction summarize =
|
||||
kernel.getSemanticFunctionBuilder()
|
||||
.withPromptTemplate(prompt)
|
||||
.withFunctionName("summarize")
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfig(0.2, 0.5, 0, 0, 2000))
|
||||
new PromptConfig.CompletionConfig(0.2, 0.5, 0, 0, 2000))
|
||||
.build();
|
||||
|
||||
if (summarize == null) {
|
||||
|
||||
+5
-5
@@ -4,8 +4,8 @@ import com.azure.ai.openai.OpenAIClientBuilder;
|
||||
import com.azure.core.credential.AzureKeyCredential;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionKernelFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -98,18 +98,18 @@ public class InlineFunctionWithPreBuiltSkillExample {
|
||||
.buildAsyncClient();
|
||||
|
||||
TextCompletion textCompletion =
|
||||
SKBuilders.textCompletion().withOpenAIClient(client).withModelId(MODEL).build();
|
||||
SKBuilders.textCompletion().withOpenAIAsyncClient(client).withModelId(MODEL).build();
|
||||
String prompt = "{{$input}}\nSummarize the content above.";
|
||||
|
||||
Kernel kernel = SKBuilders.kernel().withDefaultAIService(textCompletion).build();
|
||||
|
||||
CompletionSKFunction summarize =
|
||||
CompletionKernelFunction summarize =
|
||||
SKBuilders.completionFunctions()
|
||||
.withKernel(kernel)
|
||||
.withPromptTemplate(prompt)
|
||||
.withFunctionName("summarize")
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfig(0.2, 0.5, 0, 0, 2000))
|
||||
new PromptConfig.CompletionConfig(0.2, 0.5, 0, 0, 2000))
|
||||
.build();
|
||||
|
||||
if (summarize == null) {
|
||||
|
||||
+6
-6
@@ -6,8 +6,8 @@ import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariable;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionKernelFunction;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
@@ -47,12 +47,12 @@ public class ContextVariableFunctionTest extends AbstractKernelTest {
|
||||
User: {{$user_input}}
|
||||
ChatBot:\s""";
|
||||
|
||||
CompletionSKFunction chat =
|
||||
CompletionKernelFunction chat =
|
||||
kernel.getSemanticFunctionBuilder()
|
||||
.withPromptTemplate(prompt)
|
||||
.withFunctionName("ChatBot")
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfig(0.7, 0.5, 0, 0, 2000))
|
||||
new PromptConfig.CompletionConfig(0.7, 0.5, 0, 0, 2000))
|
||||
.build();
|
||||
|
||||
SKContext readOnlySkContext = SKBuilders.context().withKernel(kernel).build();
|
||||
@@ -74,7 +74,7 @@ public class ContextVariableFunctionTest extends AbstractKernelTest {
|
||||
.block();
|
||||
}
|
||||
|
||||
private Function<SKContext, Mono<SKContext>> chat(String input, CompletionSKFunction chat) {
|
||||
private Function<SKContext, Mono<SKContext>> chat(String input, CompletionKernelFunction chat) {
|
||||
return (context) -> {
|
||||
try {
|
||||
return chat(input, chat, context);
|
||||
@@ -84,7 +84,7 @@ public class ContextVariableFunctionTest extends AbstractKernelTest {
|
||||
};
|
||||
}
|
||||
|
||||
private Mono<SKContext> chat(String input, CompletionSKFunction chat, SKContext context)
|
||||
private Mono<SKContext> chat(String input, CompletionKernelFunction chat, SKContext context)
|
||||
throws ExecutionException, InterruptedException, TimeoutException {
|
||||
context = context.setVariable("user_input", input);
|
||||
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ package com.microsoft.semantickernel.e2e;
|
||||
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionKernelFunction;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIf;
|
||||
import org.slf4j.Logger;
|
||||
@@ -19,7 +19,7 @@ public class FunSkillTest extends AbstractKernelTest {
|
||||
Mono<SKContext> result =
|
||||
buildTextCompletionKernel()
|
||||
.importSkillFromDirectory("FunSkill", "../../../samples/skills")
|
||||
.getFunction("joke", CompletionSKFunction.class)
|
||||
.getFunction("joke", CompletionKernelFunction.class)
|
||||
.invokeAsync("time travel to dinosaur age");
|
||||
|
||||
if (result != null) {
|
||||
|
||||
+4
-4
@@ -4,8 +4,8 @@ package com.microsoft.semantickernel.e2e;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionKernelFunction;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIf;
|
||||
import org.slf4j.Logger;
|
||||
@@ -22,12 +22,12 @@ public class InlineFunctionTest extends AbstractKernelTest {
|
||||
Kernel kernel = buildTextCompletionKernel();
|
||||
String prompt = "{{$input}}\n" + "Summarize the content above.";
|
||||
|
||||
CompletionSKFunction summarize =
|
||||
CompletionKernelFunction summarize =
|
||||
kernel.getSemanticFunctionBuilder()
|
||||
.withPromptTemplate(prompt)
|
||||
.withFunctionName("summarize")
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfig(0.2, 0.5, 0, 0, 2000))
|
||||
new PromptConfig.CompletionConfig(0.2, 0.5, 0, 0, 2000))
|
||||
.build();
|
||||
|
||||
String text =
|
||||
|
||||
+4
-4
@@ -7,8 +7,8 @@ import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.textcompletion.OpenAITextCompletion;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionKernelFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.io.IOException;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -21,7 +21,7 @@ public class KernelTest extends AbstractKernelTest {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(KernelTest.class);
|
||||
|
||||
private static void executeCompletion(Kernel kernel) {
|
||||
CompletionSKFunction summarize =
|
||||
CompletionKernelFunction summarize =
|
||||
kernel.getSemanticFunctionBuilder()
|
||||
.withPromptTemplate(
|
||||
"""
|
||||
@@ -29,7 +29,7 @@ public class KernelTest extends AbstractKernelTest {
|
||||
|
||||
One line TLDR with the fewest words.""")
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfig(0, 0, 0, 0, 256))
|
||||
new PromptConfig.CompletionConfig(0, 0, 0, 0, 256))
|
||||
.build();
|
||||
|
||||
String text1 =
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import com.microsoft.semantickernel.memory.MemoryQueryResult;
|
||||
import com.microsoft.semantickernel.memory.SemanticTextMemory;
|
||||
import com.microsoft.semantickernel.memory.VolatileMemoryStore;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionKernelFunction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
@@ -84,7 +84,7 @@ public class TextEmbeddingsTest extends AbstractKernelTest {
|
||||
User: {{$userInput}}
|
||||
ChatBot:\s""";
|
||||
|
||||
CompletionSKFunction chat =
|
||||
CompletionKernelFunction chat =
|
||||
kernel.getSemanticFunctionBuilder()
|
||||
.withPromptTemplate(skPrompt)
|
||||
.withFunctionName("recall")
|
||||
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
|
||||
package com.microsoft.semantickernel.assistants;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.microsoft.semantickernel.plugin.Plugin;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.aiservices.AIService;
|
||||
import com.microsoft.semantickernel.templateengine.PromptTemplateEngine;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.SemanticFunctionConfig;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.orchestration.FunctionResult;
|
||||
import com.microsoft.semantickernel.KernelResult;
|
||||
import com.microsoft.semantickernel.memory.SemanticTextMemory;
|
||||
import com.microsoft.semantickernel.KernelConfig;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class AssistantKernel extends Plugin implements Kernel {
|
||||
|
||||
public static AssistantKernel FromConfiguration(
|
||||
String configurationFile,
|
||||
@Nullable List<AIService> aiServices,
|
||||
@Nullable List<Plugin> plugins,
|
||||
@Nullable List<PromptTemplateEngine> promptTemplateEngines
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public AssistantKernel(String name, SKFunction... functions) {
|
||||
super(name, functions);
|
||||
}
|
||||
|
||||
public SKFunction getFunction(String skill, String function) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <FunctionType extends SKFunction>FunctionType registerSemanticFunction(FunctionType func) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CompletionSKFunction registerSemanticFunction(
|
||||
String skillName, String functionName, SemanticFunctionConfig functionConfig) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T extends AIService> T getService(String serviceId, Class<T> clazz) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CompletionSKFunction.Builder getSemanticFunctionBuilder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Mono<KernelResult> runAsync(boolean b, ContextVariables variables, SKFunction... pipeline) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Mono<KernelResult> runAsync(ContextVariables variables, SKFunction... pipeline) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Mono<KernelResult> runAsync(String s, SKFunction... pipeline) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Mono<KernelResult> runAsync(SKFunction... pipeline) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public SemanticTextMemory getMemory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public PromptTemplateEngine getPromptTemplateEngine() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public KernelConfig getConfig() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<SKFunction> functions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Mono<AssistantThread> createThreadAsync() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
package com.microsoft.semantickernel.assistants;
|
||||
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public interface AssistantThread extends SKFunction {
|
||||
|
||||
public Mono addUserMessageAsync(String message);
|
||||
|
||||
}
|
||||
|
||||
-157
@@ -1,157 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.coreskills;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.text.TextChunker;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/** Semantic skill that enables conversations summarization */
|
||||
public class ConversationSummarySkill {
|
||||
// The max tokens to process in a single semantic function call.
|
||||
private static final int MaxTokens = 1024;
|
||||
|
||||
private final CompletionSKFunction summarizeConversationFunction;
|
||||
private final CompletionSKFunction conversationActionItemsFunction;
|
||||
private final CompletionSKFunction conversationTopicsFunction;
|
||||
private final Kernel kernel;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of the ConversationSummarySkill class
|
||||
*
|
||||
* @param kernel Kernel instance
|
||||
*/
|
||||
public ConversationSummarySkill(Kernel kernel) {
|
||||
this.kernel = kernel;
|
||||
this.summarizeConversationFunction =
|
||||
SKBuilders.completionFunctions()
|
||||
.withKernel(kernel)
|
||||
.withPromptTemplate(
|
||||
SemanticFunctionConstants.SummarizeConversationDefinition)
|
||||
.withFunctionName("summarize")
|
||||
.withSkillName("ConversationSummarySkill")
|
||||
.withDescription(
|
||||
"Given a section of a conversation transcript, summarize the part"
|
||||
+ " of the conversation.")
|
||||
.withCompletionConfig(
|
||||
SKBuilders.completionConfig()
|
||||
.maxTokens(MaxTokens)
|
||||
.temperature(0.1)
|
||||
.topP(0.5)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
this.conversationActionItemsFunction =
|
||||
SKBuilders.completionFunctions()
|
||||
.withKernel(kernel)
|
||||
.withPromptTemplate(
|
||||
SemanticFunctionConstants.GetConversationActionItemsDefinition)
|
||||
.withFunctionName("ActionItems")
|
||||
.withSkillName("ConversationSummarySkill")
|
||||
.withDescription(
|
||||
"Given a section of a conversation transcript, identify action"
|
||||
+ " items.")
|
||||
.withCompletionConfig(
|
||||
SKBuilders.completionConfig()
|
||||
.maxTokens(MaxTokens)
|
||||
.temperature(0.1)
|
||||
.topP(0.5)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
this.conversationTopicsFunction =
|
||||
SKBuilders.completionFunctions()
|
||||
.withKernel(kernel)
|
||||
.withPromptTemplate(
|
||||
SemanticFunctionConstants.GetConversationTopicsDefinition)
|
||||
.withFunctionName("Topics")
|
||||
.withSkillName("ConversationSummarySkill")
|
||||
.withDescription(
|
||||
"Analyze a conversation transcript and extract key topics worth"
|
||||
+ " remembering.")
|
||||
.withCompletionConfig(
|
||||
SKBuilders.completionConfig()
|
||||
.maxTokens(MaxTokens)
|
||||
.temperature(0.1)
|
||||
.topP(0.5)
|
||||
.build())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a long conversation transcript, summarize the conversation
|
||||
*
|
||||
* @param input A long conversation transcript
|
||||
* @param context The SKContext for function execution
|
||||
* @return A context containing the summarized conversation
|
||||
*/
|
||||
@DefineSKFunction(
|
||||
description = "Given a long conversation transcript, summarize the conversation.",
|
||||
name = "SummarizeConversation")
|
||||
public Mono<SKContext> summarizeConversationAsync(
|
||||
@SKFunctionInputAttribute(description = "A long conversation transcript.") String input,
|
||||
@Nullable SKContext context) {
|
||||
List<String> lines = TextChunker.splitPlainTextLines(input, MaxTokens);
|
||||
List<String> paragraphs = TextChunker.splitPlainTextParagraphs(lines, MaxTokens);
|
||||
|
||||
if (context == null) {
|
||||
context = SKBuilders.context().withSkills(kernel.getSkills()).build();
|
||||
}
|
||||
|
||||
SKContext completionContext = context.copy();
|
||||
|
||||
return this.summarizeConversationFunction.aggregatePartitionedResultsAsync(
|
||||
paragraphs, completionContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a long conversation transcript, identify action items
|
||||
*
|
||||
* @param input A long conversation transcript
|
||||
* @param context The SKContext for function execution
|
||||
* @return A context containing the action items
|
||||
*/
|
||||
@DefineSKFunction(
|
||||
description = "Given a long conversation transcript, identify action items.",
|
||||
name = "GetConversationActionItems")
|
||||
public Mono<SKContext> getConversationActionItemsAsync(
|
||||
@SKFunctionInputAttribute(description = "A long conversation transcript.") String input,
|
||||
SKContext context) {
|
||||
List<String> lines = TextChunker.splitPlainTextLines(input, MaxTokens);
|
||||
List<String> paragraphs = TextChunker.splitPlainTextParagraphs(lines, MaxTokens);
|
||||
|
||||
SKContext completionContext = context.copy();
|
||||
|
||||
return this.conversationActionItemsFunction.aggregatePartitionedResultsAsync(
|
||||
paragraphs, completionContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a long conversation transcript, identify topics
|
||||
*
|
||||
* @param input A long conversation transcript
|
||||
* @param context The SKContext for function execution
|
||||
* @return A context containing the topics
|
||||
*/
|
||||
@DefineSKFunction(
|
||||
description =
|
||||
"Given a long conversation transcript, identify topics worth remembering.",
|
||||
name = "GetConversationTopics")
|
||||
public Mono<SKContext> getConversationTopicsAsync(
|
||||
@SKFunctionInputAttribute(description = "A long conversation transcript.") String input,
|
||||
SKContext context) {
|
||||
List<String> lines = TextChunker.splitPlainTextLines(input, MaxTokens);
|
||||
List<String> paragraphs = TextChunker.splitPlainTextParagraphs(lines, MaxTokens);
|
||||
|
||||
SKContext completionContext = context.copy();
|
||||
|
||||
return this.conversationTopicsFunction.aggregatePartitionedResultsAsync(
|
||||
paragraphs, completionContext);
|
||||
}
|
||||
}
|
||||
-85
@@ -1,85 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.coreskills;
|
||||
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* Read and write from a file.
|
||||
*
|
||||
* <p>Usage: kernel.ImportSkill("file", new FileIOSkill());
|
||||
*
|
||||
* <p>Examples:
|
||||
*
|
||||
* <pre>{@code
|
||||
* file.readAsync($path) => "hello world"
|
||||
* file.writeAsync()
|
||||
* }</pre>
|
||||
*/
|
||||
public class FileIOSkill {
|
||||
|
||||
/**
|
||||
* Read a file.
|
||||
*
|
||||
* <p>Example:
|
||||
*
|
||||
* <pre>{@code
|
||||
* file.readAsync($path) => "hello world"
|
||||
* }</pre>
|
||||
*
|
||||
* @param path Source file.
|
||||
* @return File content.
|
||||
*/
|
||||
@DefineSKFunction(description = "Read a file", name = "readAsync")
|
||||
public String readFileAsync(
|
||||
@SKFunctionInputAttribute(description = "Source file") String path,
|
||||
@SKFunctionParameters(
|
||||
name = "charset",
|
||||
description = "Character set to use to read the file",
|
||||
defaultValue = "UTF-8")
|
||||
String charset)
|
||||
throws IOException {
|
||||
Path filePath = Paths.get(path);
|
||||
byte[] fileBytes;
|
||||
fileBytes = Files.readAllBytes(filePath);
|
||||
String fileContents = new String(fileBytes, Charset.forName(charset));
|
||||
return fileContents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a file.
|
||||
*
|
||||
* <p>Example:
|
||||
*
|
||||
* <pre>{@code
|
||||
* file.writeAsync()
|
||||
* }</pre>
|
||||
*
|
||||
* @param path The destination file.
|
||||
* @param content Contains the 'content' to write
|
||||
*/
|
||||
@DefineSKFunction(description = "Write a file", name = "writeAsync")
|
||||
public void writeFileAsync(
|
||||
@SKFunctionInputAttribute(description = "Destination file") String path,
|
||||
@SKFunctionParameters(
|
||||
name = "content",
|
||||
description = "File content",
|
||||
defaultValue = "",
|
||||
type = String.class)
|
||||
String content,
|
||||
@SKFunctionParameters(
|
||||
name = "charset",
|
||||
description = "Character set to use to read the file",
|
||||
defaultValue = "UTF-8")
|
||||
String charset)
|
||||
throws IOException {
|
||||
Path filePath = Paths.get(path);
|
||||
Files.write(filePath, content.getBytes(charset));
|
||||
}
|
||||
}
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.coreskills;
|
||||
|
||||
import com.azure.core.http.HttpClient;
|
||||
import com.azure.core.http.HttpMethod;
|
||||
import com.azure.core.http.HttpRequest;
|
||||
import com.azure.core.http.HttpResponse;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* A skill that provides HTTP functionality.
|
||||
*
|
||||
* <p>Usage:
|
||||
*
|
||||
* <p>Usage: kernel.importSkill(new HttpSkill(), "http");
|
||||
*
|
||||
* <p>Examples:
|
||||
*
|
||||
* <p>{{http.getAsync $url}}
|
||||
*
|
||||
* <p>{{http.postAsync $url}}
|
||||
*
|
||||
* <p>{{http.putAsync $url}}
|
||||
*
|
||||
* <p>{{http.deleteAsync $url}}
|
||||
*/
|
||||
public class HttpSkill {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
public HttpSkill() {
|
||||
this.httpClient = HttpClient.createDefault();
|
||||
}
|
||||
|
||||
public HttpSkill(HttpClient httpClient) {
|
||||
this.httpClient = httpClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an HTTP GET request to the specified URI and returns body as a string.
|
||||
*
|
||||
* @param url The URI to send the request to.
|
||||
* @return The response body as a string.
|
||||
*/
|
||||
public Mono<String> getAsync(String url) {
|
||||
if (url == null || url.isEmpty()) {
|
||||
return Mono.error(new IllegalArgumentException("url cannot be `null` or empty"));
|
||||
}
|
||||
HttpRequest request = new HttpRequest(HttpMethod.GET, url);
|
||||
return httpClient.send(request).flatMap(response -> response.getBodyAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an HTTP POST request to the specified URI and returns body as a string.
|
||||
*
|
||||
* @param url The URI to send the request to.
|
||||
* @param body The response body as a string.
|
||||
* @return
|
||||
*/
|
||||
public Mono<String> postAsync(String url, String body) {
|
||||
if (url == null || url.isEmpty()) {
|
||||
return Mono.error(new IllegalArgumentException("url cannot be `null` or empty"));
|
||||
}
|
||||
HttpRequest request = new HttpRequest(HttpMethod.POST, url);
|
||||
request.setBody(body);
|
||||
return httpClient.send(request).flatMap(response -> response.getBodyAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an HTTP PUT request to the specified URI and returns body as a string.
|
||||
*
|
||||
* @param url The URI to send the request to.
|
||||
* @param body The response body as a string.
|
||||
* @return
|
||||
*/
|
||||
public Mono<String> putAsync(String url, String body) {
|
||||
if (url == null || url.isEmpty()) {
|
||||
return Mono.error(new IllegalArgumentException("url cannot be `null` or empty"));
|
||||
}
|
||||
HttpRequest request = new HttpRequest(HttpMethod.PUT, url);
|
||||
request.setBody(body);
|
||||
return httpClient.send(request).flatMap(response -> response.getBodyAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an HTTP DELETE request to the specified URI and returns body as a string.
|
||||
*
|
||||
* @param url The URI to send the request to.
|
||||
* @return The response body as a string.
|
||||
*/
|
||||
public Mono<HttpResponse> deleteAsync(String url) {
|
||||
if (url == null || url.isEmpty()) {
|
||||
return Mono.error(new IllegalArgumentException("url cannot be `null` or empty"));
|
||||
}
|
||||
HttpRequest request = new HttpRequest(HttpMethod.DELETE, url);
|
||||
return httpClient.send(request).flatMap(response -> Mono.just(response));
|
||||
}
|
||||
}
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.coreskills;
|
||||
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* MathSkill provides a set of functions to make Math calculations.
|
||||
*
|
||||
* <ul>
|
||||
* <li><code>input</code> is the first number in the operation.
|
||||
* <li><code>amount</code> is the second number in the operation.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Usage:
|
||||
*
|
||||
* <blockquote>
|
||||
*
|
||||
* <pre>
|
||||
* kernel.ImportSkill("math", new MathSkill());
|
||||
*
|
||||
* {{math.add}} => Returns the sum of input and amount
|
||||
* {{math.subtract}} => Returns the differentce of input from amount
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote>
|
||||
*
|
||||
* <p>This skill uses BigDecimal to perform the number conversion and the calculations.
|
||||
*/
|
||||
public class MathSkill {
|
||||
|
||||
/**
|
||||
* Returns the addition result of input and amount values provided.
|
||||
*
|
||||
* <p>This skill attempts to convert the numbers to BigDecimal and then add them.
|
||||
*
|
||||
* <p>If a conversion error occurs, the skill will throw an exception.
|
||||
*
|
||||
* @param input Initial value as string to add the specified amount
|
||||
* @param amount The amount to be added to input
|
||||
* @return The resulting sum as a String.
|
||||
*/
|
||||
@DefineSKFunction(description = "Adds amount to a value.", name = "add")
|
||||
public String add(
|
||||
@SKFunctionInputAttribute(description = "The value to add to.") String input,
|
||||
@SKFunctionParameters(name = "amount", description = "The amount to be added to value.")
|
||||
String amount) {
|
||||
|
||||
BigDecimal bValue = new BigDecimal(input);
|
||||
|
||||
return bValue.add(new BigDecimal(amount)).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subtraction result of input and amount values provided.
|
||||
*
|
||||
* <p>This skill attempts to convert the numbers to BigDecimal and then subtract them.
|
||||
*
|
||||
* <p>If a conversion error occurs, the skill will throw an exception.
|
||||
*
|
||||
* @param input Initial value as string to subtract the specified amount
|
||||
* @param amount The amount to be subtracted from input
|
||||
* @return The resulting difference as a String.
|
||||
*/
|
||||
@DefineSKFunction(description = "Subtracts amount from value.", name = "Subtract")
|
||||
public String subtract(
|
||||
@SKFunctionInputAttribute(description = "The value to subtract from.") String input,
|
||||
@SKFunctionParameters(
|
||||
name = "amount",
|
||||
description = "The amount to be subtracted from value.")
|
||||
String amount) {
|
||||
|
||||
BigDecimal bValue = new BigDecimal(input);
|
||||
|
||||
return bValue.subtract(new BigDecimal(amount)).toString();
|
||||
}
|
||||
}
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.coreskills;
|
||||
|
||||
class SemanticFunctionConstants {
|
||||
public static final String SummarizeConversationDefinition =
|
||||
"BEGIN CONTENT TO SUMMARIZE:\n"
|
||||
+ "{{$INPUT}}\n"
|
||||
+ "\n"
|
||||
+ "END CONTENT TO SUMMARIZE.\n"
|
||||
+ "\n"
|
||||
+ "Summarize the conversation in 'CONTENT TO SUMMARIZE', identifying main points of"
|
||||
+ " discussion and any conclusions that were reached.\n"
|
||||
+ "Do not incorporate other general knowledge.\n"
|
||||
+ "Summary is in plain text, in complete sentences, with no markup or tags.\n"
|
||||
+ "\n"
|
||||
+ "BEGIN SUMMARY:";
|
||||
|
||||
public static final String GetConversationActionItemsDefinition =
|
||||
"You are an action item extractor. You will be given chat history and need to make note"
|
||||
+ " of action items mentioned in the chat.\n"
|
||||
+ "Extract action items from the content if there are any. If there are no action,"
|
||||
+ " return nothing. If a single field is missing, use an empty string.\n"
|
||||
+ "Return the action items in json.\n"
|
||||
+ "\n"
|
||||
+ "Possible statuses for action items are: Open, Closed, In Progress.\n"
|
||||
+ "\n"
|
||||
+ "EXAMPLE INPUT WITH ACTION ITEMS:\n"
|
||||
+ "\n"
|
||||
+ "John Doe said: \"I will record a demo for the new feature by Friday\"\n"
|
||||
+ "I said: \"Great, thanks John. We may not use all of it but it's good to get it"
|
||||
+ " out there.\"\n"
|
||||
+ "\n"
|
||||
+ "EXAMPLE OUTPUT:\n"
|
||||
+ "{\n"
|
||||
+ " \"actionItems\": [\n"
|
||||
+ " {\n"
|
||||
+ " \"owner\": \"John Doe\",\n"
|
||||
+ " \"actionItem\": \"Record a demo for the new feature\",\n"
|
||||
+ " \"dueDate\": \"Friday\",\n"
|
||||
+ " \"status\": \"Open\",\n"
|
||||
+ " \"notes\": \"\"\n"
|
||||
+ " }\n"
|
||||
+ " ]\n"
|
||||
+ "}\n"
|
||||
+ "\n"
|
||||
+ "EXAMPLE INPUT WITHOUT ACTION ITEMS:\n"
|
||||
+ "\n"
|
||||
+ "John Doe said: \"Hey I'm going to the store, do you need anything?\"\n"
|
||||
+ "I said: \"No thanks, I'm good.\"\n"
|
||||
+ "\n"
|
||||
+ "EXAMPLE OUTPUT:\n"
|
||||
+ "{\n"
|
||||
+ " \"action_items\": []\n"
|
||||
+ "}\n"
|
||||
+ "\n"
|
||||
+ "CONTENT STARTS HERE.\n"
|
||||
+ "\n"
|
||||
+ "{{$INPUT}}\n"
|
||||
+ "\n"
|
||||
+ "CONTENT STOPS HERE.\n"
|
||||
+ "\n"
|
||||
+ "OUTPUT:";
|
||||
|
||||
public static final String GetConversationTopicsDefinition =
|
||||
"Analyze the following extract taken from a conversation transcript and extract key"
|
||||
+ " topics.\n"
|
||||
+ "- Topics only worth remembering.\n"
|
||||
+ "- Be brief. Short phrases.\n"
|
||||
+ "- Can use broken English.\n"
|
||||
+ "- Conciseness is very important.\n"
|
||||
+ "- Topics can include names of memories you want to recall.\n"
|
||||
+ "- NO LONG SENTENCES. SHORT PHRASES.\n"
|
||||
+ "- Return in JSON\n"
|
||||
+ "[Input]\n"
|
||||
+ "My name is Macbeth. I used to be King of Scotland, but I died. My wife's name is"
|
||||
+ " Lady Macbeth and we were married for 15 years. We had no children. Our beloved"
|
||||
+ " dog Toby McDuff was a famous hunter of rats in the forest.\n"
|
||||
+ "My tragic story was immortalized by Shakespeare in a play.\n"
|
||||
+ "[Output]\n"
|
||||
+ "{\n"
|
||||
+ " \"topics\": [\n"
|
||||
+ " \"Macbeth\",\n"
|
||||
+ " \"King of Scotland\",\n"
|
||||
+ " \"Lady Macbeth\",\n"
|
||||
+ " \"Dog\",\n"
|
||||
+ " \"Toby McDuff\",\n"
|
||||
+ " \"Shakespeare\",\n"
|
||||
+ " \"Play\",\n"
|
||||
+ " \"Tragedy\"\n"
|
||||
+ " ]\n"
|
||||
+ "}\n"
|
||||
+ "+++++\n"
|
||||
+ "[Input]\n"
|
||||
+ "{{$INPUT}}\n"
|
||||
+ "[Output]";
|
||||
}
|
||||
-248
@@ -1,248 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.coreskills;
|
||||
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.memory.MemoryException;
|
||||
import com.microsoft.semantickernel.memory.MemoryQueryResult;
|
||||
import com.microsoft.semantickernel.memory.MemoryRecordMetadata;
|
||||
import com.microsoft.semantickernel.memory.SemanticTextMemory;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nonnull;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* TextMemorySkill provides a skill to save or recall information from the long or short term.
|
||||
* Usage: {@code kernel.ImportSkill(new TextMemorySkill(), "memory");} Example: {@code
|
||||
* {{memory.recall "what is the capital of France?" }} => "Paris"}
|
||||
*/
|
||||
public class TextMemorySkill {
|
||||
|
||||
/** Name of the context variable used to specify which memory collection to use. */
|
||||
public static final String COLLECTION_PARAM = "collection";
|
||||
|
||||
/** Name of the context variable used to specify the information to store. */
|
||||
public static final String INFO_PARAM = "info";
|
||||
|
||||
/** Name of the context variable used to specify the input to the skill. */
|
||||
public static final String INPUT_PARAM = "input";
|
||||
|
||||
/** Name of the context variable used to specify memory search relevance score. */
|
||||
public static final String RELEVANCE_PARAM = "relevance";
|
||||
|
||||
/**
|
||||
* Name of the context variable used to specify a unique key associated with stored information.
|
||||
*/
|
||||
public static final String KEY_PARAM = "key";
|
||||
|
||||
/** Name of the context variable used to specify the number of memories to recall */
|
||||
public static final String LIMIT_PARAM = "limit";
|
||||
|
||||
/** Default value for the collection name. */
|
||||
public static final String DEFAULT_COLLECTION = "generic";
|
||||
|
||||
/** Default value for the relevance score. */
|
||||
public static final String DEFAULT_RELEVANCE = "0.75";
|
||||
|
||||
/** Default value for the limit. */
|
||||
public static final String DEFAULT_LIMIT = "1";
|
||||
|
||||
/**
|
||||
* Key-based lookup for a specific memory.
|
||||
*
|
||||
* @param collection The collection containing the memory to retrieve
|
||||
* @param key The key associated with the memory to retrieve
|
||||
* @param context The context containing the semantic memory
|
||||
* @return The memory associated with the key
|
||||
*/
|
||||
@DefineSKFunction(description = "Key-based lookup for a specific memory", name = "Retrieve")
|
||||
public Mono<String> retrieveAsync(
|
||||
@SKFunctionParameters(
|
||||
name = COLLECTION_PARAM,
|
||||
description =
|
||||
"Memories collection associated with the memory to retrieve",
|
||||
defaultValue = DEFAULT_COLLECTION)
|
||||
String collection,
|
||||
@SKFunctionParameters(
|
||||
name = KEY_PARAM,
|
||||
description = "The key associated with the memory to retrieve")
|
||||
String key,
|
||||
SKContext context) {
|
||||
|
||||
SemanticTextMemory memory = context.getSemanticMemory();
|
||||
|
||||
if (memory == null) {
|
||||
return Mono.error(new RuntimeException("Memory not present"));
|
||||
}
|
||||
|
||||
return memory.getAsync(collection, key, false)
|
||||
.map(it -> it.getMetadata().getText())
|
||||
.defaultIfEmpty("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Save information to semantic memory.
|
||||
*
|
||||
* @param info The information to save
|
||||
* @param collection Memories collection associated with the information to save
|
||||
* @param key The key associated with the information to save
|
||||
* @param context The context containing the semantic memory
|
||||
* @return The key associated with the saved information
|
||||
*/
|
||||
@DefineSKFunction(description = "Save information to semantic memory", name = "Save")
|
||||
public Mono<SKContext> saveAsync(
|
||||
@SKFunctionParameters(
|
||||
name = INFO_PARAM,
|
||||
description = "The information to save",
|
||||
defaultValue = "",
|
||||
type = String.class)
|
||||
String info,
|
||||
@SKFunctionParameters(
|
||||
name = COLLECTION_PARAM,
|
||||
description =
|
||||
"Memories collection associated with the information to save",
|
||||
defaultValue = DEFAULT_COLLECTION,
|
||||
type = String.class)
|
||||
String collection,
|
||||
@SKFunctionParameters(
|
||||
name = KEY_PARAM,
|
||||
description = "The key associated with the information to save",
|
||||
defaultValue = "",
|
||||
type = String.class)
|
||||
String key,
|
||||
SKContext context) {
|
||||
|
||||
SemanticTextMemory memory = context.getSemanticMemory();
|
||||
if (memory == null) {
|
||||
return Mono.error(
|
||||
new MemoryException(MemoryException.ErrorCodes.UNKNOWN, "Memory not present"));
|
||||
}
|
||||
|
||||
return memory.saveInformationAsync(collection, info, key, null, null)
|
||||
.map(
|
||||
it -> {
|
||||
context.setVariable(TextMemorySkill.KEY_PARAM, it);
|
||||
return SKBuilders.context()
|
||||
.withVariables(context.getVariables())
|
||||
.withSkills(context.getSkills())
|
||||
.withMemory(context.getSemanticMemory())
|
||||
.build();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Semantic search and return up to N memories related to the input text
|
||||
*
|
||||
* @param input The input text to find related memories for
|
||||
* @param collection Memories collection to search
|
||||
* @param relevance The relevance score, from 0.0 to 1.0, where 1.0 means perfect match
|
||||
* @param limit The maximum number of relevant memories to recall
|
||||
* @param context Contains the memory to search
|
||||
* @return The list of memories related to the input text
|
||||
*/
|
||||
@DefineSKFunction(
|
||||
description = "Semantic search and return up to N memories related to the input text",
|
||||
name = "Recall")
|
||||
public Mono<List<String>> recallAsync(
|
||||
@SKFunctionParameters(
|
||||
name = INPUT_PARAM,
|
||||
description = "The information to recall",
|
||||
defaultValue = "",
|
||||
type = String.class)
|
||||
@Nonnull
|
||||
String input,
|
||||
@SKFunctionParameters(
|
||||
name = COLLECTION_PARAM,
|
||||
description =
|
||||
"Memories collection associated with the information to recall",
|
||||
defaultValue = DEFAULT_COLLECTION,
|
||||
type = String.class)
|
||||
String collection,
|
||||
@SKFunctionParameters(
|
||||
name = RELEVANCE_PARAM,
|
||||
description =
|
||||
"The relevance score, from 0.0 to 1.0, where 1.0 means perfect"
|
||||
+ " match",
|
||||
defaultValue = DEFAULT_RELEVANCE,
|
||||
type = Double.class)
|
||||
double relevance,
|
||||
@SKFunctionParameters(
|
||||
name = LIMIT_PARAM,
|
||||
description = "The maximum number of relevant memories to recall",
|
||||
defaultValue = DEFAULT_LIMIT,
|
||||
type = Integer.class)
|
||||
int limit,
|
||||
@Nonnull SKContext context) {
|
||||
|
||||
SemanticTextMemory memory = context.getSemanticMemory();
|
||||
if (memory == null) {
|
||||
return Mono.error(
|
||||
new MemoryException(MemoryException.ErrorCodes.UNKNOWN, "Memory not present"));
|
||||
}
|
||||
|
||||
// TODO: 1.0 fix cast
|
||||
// Validate parameters
|
||||
if (collection == null || collection.trim().isEmpty()) {
|
||||
if (context.getVariables().get(TextMemorySkill.COLLECTION_PARAM) == null) {
|
||||
collection = DEFAULT_COLLECTION;
|
||||
} else {
|
||||
collection =
|
||||
context.getVariables().get(TextMemorySkill.COLLECTION_PARAM).toString();
|
||||
}
|
||||
}
|
||||
final String _collection = collection;
|
||||
final float _relevance = (float) Math.min(1.0, Math.max(0.0, relevance));
|
||||
final int _limit = Math.max(1, limit);
|
||||
|
||||
// context.Log.LogTrace("Searching memories in collection '{0}', relevance '{1}'",
|
||||
// collection, relevance);
|
||||
|
||||
// Search memory
|
||||
return memory.searchAsync(_collection, input, _limit, _relevance, false)
|
||||
.flatMap(
|
||||
results -> {
|
||||
List<String> memories =
|
||||
results.stream()
|
||||
.map(MemoryQueryResult::getMetadata)
|
||||
.map(MemoryRecordMetadata::getText)
|
||||
.collect(Collectors.toList());
|
||||
return Mono.just(memories);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove information from semantic memory
|
||||
*
|
||||
* @param collection Memories collection associated with the information to remove
|
||||
* @param key The key associated with the information to remove
|
||||
* @param context Contains the memory to remove
|
||||
* @return The reactive stream
|
||||
*/
|
||||
@DefineSKFunction(description = "Remove information from semantic memory", name = "Remove")
|
||||
public Mono<Void> removeAsync(
|
||||
@SKFunctionParameters(
|
||||
name = COLLECTION_PARAM,
|
||||
description =
|
||||
"Memories collection associated with the information to remove",
|
||||
defaultValue = DEFAULT_COLLECTION,
|
||||
type = String.class)
|
||||
String collection,
|
||||
@SKFunctionParameters(
|
||||
name = KEY_PARAM,
|
||||
description = "The key associated with the information to remove",
|
||||
defaultValue = "",
|
||||
type = String.class)
|
||||
String key,
|
||||
SKContext context) {
|
||||
SemanticTextMemory memory = context.getSemanticMemory();
|
||||
if (memory == null) {
|
||||
return Mono.error(
|
||||
new MemoryException(MemoryException.ErrorCodes.UNKNOWN, "Memory not present"));
|
||||
}
|
||||
|
||||
return memory.removeAsync(collection, key);
|
||||
}
|
||||
}
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.coreskills;
|
||||
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import java.util.Locale;
|
||||
|
||||
/** TextSkill provides a set of functions to manipulate strings. */
|
||||
public class TextSkill {
|
||||
|
||||
@DefineSKFunction(description = "Change all string chars to uppercase.", name = "Uppercase")
|
||||
public String uppercase(
|
||||
@SKFunctionInputAttribute(description = "Text to uppercase") String text) {
|
||||
return text.toUpperCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
@DefineSKFunction(description = "Remove spaces to the left of a string.", name = "LStrip")
|
||||
public String lStrip(@SKFunctionInputAttribute(description = "Text to edit") String text) {
|
||||
return text.replaceAll("^ +", "");
|
||||
}
|
||||
|
||||
@DefineSKFunction(description = "Remove spaces to the right of a string.", name = "RStrip")
|
||||
public String rStrip(@SKFunctionInputAttribute(description = "Text to edit") String text) {
|
||||
return text.replaceAll(" +$", "");
|
||||
}
|
||||
|
||||
@DefineSKFunction(
|
||||
description = "Remove spaces to the left and right of a string",
|
||||
name = "Strip")
|
||||
public String strip(@SKFunctionInputAttribute(description = "Text to edit") String input) {
|
||||
return input.trim();
|
||||
}
|
||||
|
||||
@DefineSKFunction(description = "Change all string chars to lowercase", name = "lowercase")
|
||||
public String lowercase(
|
||||
@SKFunctionInputAttribute(description = "Text to lowercase") String input) {
|
||||
return input.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
-428
@@ -1,428 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.coreskills;
|
||||
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import com.microsoft.semantickernel.util.LocaleParser;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.TextStyle;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Description: TimeSkill provides a set of functions to get the current time and date.
|
||||
*
|
||||
* <p>Usage: kernel.importSkill(new TimeSkill(), "time");
|
||||
*
|
||||
* <p>Examples:
|
||||
*
|
||||
* <p>{{time.date}} => Sunday, 12 January, 2031
|
||||
*
|
||||
* <p>{{time.today}} => Sunday, 12 January, 2031
|
||||
*
|
||||
* <p>{{time.now}} => Sunday, January 12, 2031 9:15 PM
|
||||
*
|
||||
* <p>{{time.utcNow}} => Sunday, January 13, 2031 5:15 AM
|
||||
*
|
||||
* <p>{{time.time}} => 09:15:07 PM
|
||||
*
|
||||
* <p>{{time.year}} => 2031
|
||||
*
|
||||
* <p>{{time.month}} => January
|
||||
*
|
||||
* <p>{{time.monthNumber}} => 01
|
||||
*
|
||||
* <p>{{time.day}} => 12
|
||||
*
|
||||
* <p>{{time.dayOfWeek}} => Sunday
|
||||
*
|
||||
* <p>{{time.hour}} => 9 PM
|
||||
*
|
||||
* <p>{{time.hourNumber}} => 21
|
||||
*
|
||||
* <p>{{time.days_ago $days}} => Sunday, 7 May, 2023
|
||||
*
|
||||
* <p>{{time.last_matching_day $dayName}} => Sunday, 7 May, 2023
|
||||
*
|
||||
* <p>{{time.minute}} => 15
|
||||
*
|
||||
* <p>{{time.second}} => 7
|
||||
*
|
||||
* <p>{{time.timeZoneOffset}} => -08:00
|
||||
*
|
||||
* <p>{{time.timeZoneName}} => Pacific Time
|
||||
*/
|
||||
public class TimeSkill {
|
||||
|
||||
public static final String DAY_MONTH_DAY_YEAR = "EEEE, MMMM d, yyyy";
|
||||
|
||||
/**
|
||||
* Get the current date and time for the system default timezone.
|
||||
*
|
||||
* @return a ZonedDateTime object with the current date and time.
|
||||
*/
|
||||
public ZonedDateTime now() {
|
||||
return ZonedDateTime.now(ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current date.
|
||||
*
|
||||
* <p>Example: {{time.date}} => Sunday, January 12, 2025
|
||||
*
|
||||
* @return The current date.
|
||||
*/
|
||||
@DefineSKFunction(name = "date", description = "Get the current date")
|
||||
public String date(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
// Example: Sunday, 12 January, 2025
|
||||
return DateTimeFormatter.ofPattern(DAY_MONTH_DAY_YEAR)
|
||||
.withLocale(parseLocale(locale))
|
||||
.format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current time.
|
||||
*
|
||||
* <p>Example: {{time.time}} => 9:15:00 AM
|
||||
*
|
||||
* @return The current time.
|
||||
*/
|
||||
@DefineSKFunction(name = "time", description = "Get the current time")
|
||||
public String time(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
// Example: 09:15:07 PM
|
||||
return DateTimeFormatter.ofPattern("hh:mm:ss a")
|
||||
.withLocale(parseLocale(locale))
|
||||
.format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current UTC date and time.
|
||||
*
|
||||
* <p>Example: {{time.utcNow}} => Sunday, January 13, 2025 5:15 AM
|
||||
*
|
||||
* @return The current UTC date and time.
|
||||
*/
|
||||
@DefineSKFunction(name = "utcNow", description = "Get the current UTC date and time")
|
||||
public String utcNow(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern(DAY_MONTH_DAY_YEAR + " h:mm a")
|
||||
.withLocale(parseLocale(locale))
|
||||
.format(now().withZoneSameInstant(ZoneOffset.UTC));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current date (alias for date() method).
|
||||
*
|
||||
* <p>Example: {{time.today}} => Sunday, January 12, 2025
|
||||
*
|
||||
* @return The current date.
|
||||
*/
|
||||
@DefineSKFunction(name = "today", description = "Get the current date")
|
||||
public String today(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return date(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current date and time in the local time zone.
|
||||
*
|
||||
* <p>Example: {{time.now}} => Sunday, January 12, 2025 9:15 AM
|
||||
*
|
||||
* @return The current date and time in the local time zone.
|
||||
*/
|
||||
@DefineSKFunction(
|
||||
name = "now",
|
||||
description = "Get the current date and time in the local time zone")
|
||||
public String now(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern(DAY_MONTH_DAY_YEAR + " h:mm a")
|
||||
.withLocale(parseLocale(locale))
|
||||
.format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current year.
|
||||
*
|
||||
* <p>Example: {{time.year}} => 2025
|
||||
*
|
||||
* @return The current year.
|
||||
*/
|
||||
@DefineSKFunction(name = "year", description = "Get the current year")
|
||||
public String year(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("yyyy").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current month name.
|
||||
*
|
||||
* <p>Example: {{time.month}} => January
|
||||
*
|
||||
* @return The current month name.
|
||||
*/
|
||||
@DefineSKFunction(name = "month", description = "Get the current month name")
|
||||
public String month(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("MMMM").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current month number.
|
||||
*
|
||||
* <p>Example: {{time.monthNumber}} => 01
|
||||
*
|
||||
* @return The current month number.
|
||||
*/
|
||||
@DefineSKFunction(name = "monthNumber", description = "Get the current month number")
|
||||
public String monthNumber(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("MM").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current day of the month.
|
||||
*
|
||||
* <p>Example: {{time.day}} => 12
|
||||
*
|
||||
* @return The current day of the month.
|
||||
*/
|
||||
@DefineSKFunction(name = "day", description = "Get the current day of the month")
|
||||
public String day(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("d").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current day of the week.
|
||||
*
|
||||
* <p>Example: {{time.dayOfWeek}} => Sunday
|
||||
*
|
||||
* @return The current day of the week.
|
||||
*/
|
||||
@DefineSKFunction(name = "dayOfWeek", description = "Get the current day of the week")
|
||||
public String dayOfWeek(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("EEEE").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current clock hour.
|
||||
*
|
||||
* <p>Example: {{time.hour}} => 9 AM
|
||||
*
|
||||
* @return The current clock hour.
|
||||
*/
|
||||
@DefineSKFunction(name = "hour", description = "Get the current clock hour")
|
||||
public String hour(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("h a").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current clock 24-hour number.
|
||||
*
|
||||
* <p>Example: {{time.hourNumber}} => 09
|
||||
*
|
||||
* @return The current clock 24-hour number.
|
||||
*/
|
||||
@DefineSKFunction(name = "hourNumber", description = "Get the current clock 24-hour number")
|
||||
public String hourNumber(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("HH").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the date of offset from today by a provided number of days
|
||||
*
|
||||
* <p>Example: SKContext context = SKBuilders.context().build(); context.setVariable("input",
|
||||
* "3"); {{time.daysAgo $input}} => Saturday, January 11, 2031
|
||||
*
|
||||
* @param days Number of days to subtract from the current day
|
||||
* @return The date of offset from today by a provided number of days
|
||||
*/
|
||||
@DefineSKFunction(
|
||||
name = "daysAgo",
|
||||
description = "Get the date of offset from today by a provided number of days")
|
||||
public String daysAgo(
|
||||
@SKFunctionInputAttribute(description = "Number of days to offset from today.")
|
||||
String days,
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
int offsetDays = Integer.parseInt(days);
|
||||
return DateTimeFormatter.ofPattern(DAY_MONTH_DAY_YEAR)
|
||||
.withLocale(parseLocale(locale))
|
||||
.format(now().minusDays(offsetDays));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the date of the last day matching the supplied week day name
|
||||
*
|
||||
* <p>Example: {{time.dateMatchingLastDayName "Monday"}} => Monday, January 6, 2031
|
||||
*
|
||||
* @param dayName Name of the day to match
|
||||
* @return The date of the last day matching the supplied week day name
|
||||
*/
|
||||
@DefineSKFunction(
|
||||
name = "dateMatchingLastDayName",
|
||||
description = "Get the date of the last day matching the supplied week day name")
|
||||
public String dateMatchingLastDayName(
|
||||
@SKFunctionInputAttribute(description = "Week name day.") String dayName,
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
ZonedDateTime currentDate = now();
|
||||
for (int i = 1; i <= 7; i++) {
|
||||
currentDate = currentDate.minusDays(1);
|
||||
String currentDayName =
|
||||
currentDate.getDayOfWeek().getDisplayName(TextStyle.FULL, parseLocale(locale));
|
||||
|
||||
if (currentDayName.equalsIgnoreCase(dayName)) {
|
||||
return DateTimeFormatter.ofPattern(DAY_MONTH_DAY_YEAR)
|
||||
.withLocale(parseLocale(locale))
|
||||
.format(currentDate);
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("dayName is not recognized");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minutes on the current hour.
|
||||
*
|
||||
* <p>Example: {{time.minute}} => 15
|
||||
*
|
||||
* @return The minutes on the current hour.
|
||||
*/
|
||||
@DefineSKFunction(name = "minute", description = "Get the minutes on the current hour")
|
||||
public String minute(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("mm").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the seconds on the current minute.
|
||||
*
|
||||
* <p>Example: {{time.second}} => 00
|
||||
*
|
||||
* @return The seconds on the current minute.
|
||||
*/
|
||||
@DefineSKFunction(name = "second", description = "Get the seconds on the current minute")
|
||||
public String second(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("ss").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local time zone offset from UTC.
|
||||
*
|
||||
* <p>Example: {{time.timeZoneOffset}} => +03:00
|
||||
*
|
||||
* @return The local time zone offset from UTC.
|
||||
*/
|
||||
@DefineSKFunction(
|
||||
name = "timeZoneOffset",
|
||||
description = "Get the local time zone offset from UTC")
|
||||
public String timeZoneOffset(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
return DateTimeFormatter.ofPattern("XXX").withLocale(parseLocale(locale)).format(now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the local time zone name.
|
||||
*
|
||||
* <p>Example: {{time.timeZoneName}} => Pacific Time
|
||||
*
|
||||
* @return The local time zone name.
|
||||
*/
|
||||
@DefineSKFunction(name = "timeZoneName", description = "Get the local time zone name")
|
||||
public String timeZoneName(
|
||||
@SKFunctionParameters(
|
||||
name = "locale",
|
||||
description = "Locale to use when formatting the date",
|
||||
required = false)
|
||||
String locale) {
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
return zoneId.getDisplayName(TextStyle.FULL, parseLocale(locale));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the locale string into a Locale object.
|
||||
*
|
||||
* <p>By default, it parses using the LocaleParser utility class.
|
||||
*
|
||||
* @param locale string
|
||||
* @return a locale object
|
||||
*/
|
||||
protected Locale parseLocale(String locale) {
|
||||
return LocaleParser.parseLocale(locale);
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.coreskills;
|
||||
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import java.time.Duration;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/** WaitSkill provides a set of functions to wait before making the rest of operations. */
|
||||
public class WaitSkill {
|
||||
|
||||
/**
|
||||
* Wait for a certain number of seconds.
|
||||
*
|
||||
* <p>Examples:
|
||||
*
|
||||
* <p>SKContext context = SKBuilders.context().build();
|
||||
*
|
||||
* <p>context.setVariable("input","10");
|
||||
*
|
||||
* <p>{{wait.seconds $input}}
|
||||
*
|
||||
* @param seconds The number of seconds to wait as a string.
|
||||
* @return A Mono that completes after the specified delay.
|
||||
* @throws IllegalArgumentException If the input is not a valid number.
|
||||
*/
|
||||
@DefineSKFunction(name = "seconds", description = "Wait a given amount of seconds")
|
||||
public Mono<Void> wait(String seconds) {
|
||||
try {
|
||||
double sec = Math.max(Double.parseDouble(seconds), 0);
|
||||
long milliseconds = (long) (sec * 1000);
|
||||
return Mono.delay(Duration.ofMillis(milliseconds)).then();
|
||||
} catch (NumberFormatException e) {
|
||||
return Mono.error(new IllegalArgumentException("seconds text must be a number", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -1,9 +1,11 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.util;
|
||||
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter;
|
||||
|
||||
|
||||
/**
|
||||
* Locale parser to support Java 8 and Java 9+ due to JEP 252.
|
||||
*
|
||||
@@ -29,7 +31,7 @@ public final class LocaleParser {
|
||||
|
||||
if (locale == null
|
||||
|| "".equals(locale.trim())
|
||||
|| SKFunctionParameters.NO_DEFAULT_VALUE.equals(locale)) {
|
||||
|| KernelFunctionParameter.NO_DEFAULT_VALUE.equals(locale)) {
|
||||
return Locale.getDefault();
|
||||
} else if (locale.indexOf("-") > -1) {
|
||||
parsedLocale = Locale.forLanguageTag(locale);
|
||||
|
||||
+7
-9
@@ -13,7 +13,7 @@
|
||||
<description>Parent pom for the Semantic Kernel Project</description>
|
||||
|
||||
<properties>
|
||||
<azure-ai-openai.version>1.0.0-beta.5</azure-ai-openai.version>
|
||||
<azure-ai-openai.version>1.0.0-beta.6</azure-ai-openai.version>
|
||||
<checkstyle.version>10.12.2</checkstyle.version>
|
||||
<com.uber.nullaway.version>0.10.10</com.uber.nullaway.version>
|
||||
<google.errorprone.core.version>2.19.1</google.errorprone.core.version>
|
||||
@@ -72,16 +72,14 @@
|
||||
<!-- <module>connectors/semantickernel-connectors-memory-mysql</module>-->
|
||||
|
||||
<module>aiservices/azureopenai</module>
|
||||
<module>aiservices/huggingface</module>
|
||||
<module>aiservices/ollama</module>
|
||||
<!-- <module>aiservices/huggingface</module>-->
|
||||
<!-- <module>aiservices/ollama</module>-->
|
||||
<module>aiservices/openai</module>
|
||||
|
||||
<module>misc/semantickernel-gpt3-tokenizer</module>
|
||||
<module>misc/semantickernel-settings-loader</module>
|
||||
<!-- <module>misc/semantickernel-gpt3-tokenizer</module>-->
|
||||
<!-- <module>misc/semantickernel-settings-loader</module>-->
|
||||
|
||||
<!--
|
||||
<module>plugins/semantickernel-planners</module>
|
||||
-->
|
||||
<!-- <module>plugins/semantickernel-planners</module>-->
|
||||
<module>plugins/semantickernel-plugin-core</module>
|
||||
|
||||
<module>semantickernel-bom</module>
|
||||
@@ -727,7 +725,7 @@
|
||||
<profile>
|
||||
<id>with-samples</id>
|
||||
<modules>
|
||||
<module>samples/sk-v1</module>
|
||||
<module>samples</module>
|
||||
<!-- <module>api-test</module>-->
|
||||
</modules>
|
||||
</profile>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
@@ -10,9 +11,9 @@
|
||||
<description>Parent pom for sample code for using the Semantic Kernel project</description>
|
||||
|
||||
<modules>
|
||||
<!-- <module>sample-code</module>
|
||||
<module>semantickernel-samples-guice</module> -->
|
||||
<!-- <module>semantickernel-samples-guice</module> -->
|
||||
<module>sk-v1</module>
|
||||
<module>sample-code</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
||||
@@ -18,15 +18,15 @@
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-api</artifactId>
|
||||
</dependency>
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-connectors-ai-openai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-core</artifactId>
|
||||
<!-- TODO: scope should be runtime, but VolatileMemoryStore is an issue -->
|
||||
<!-- <scope>runtime</scope> -->
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
@@ -36,6 +36,7 @@
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-connectors-memory-azurecognitivesearch</artifactId>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
@@ -52,6 +53,7 @@
|
||||
<artifactId>log4j-slf4j2-impl</artifactId>
|
||||
<version>2.20.0</version>
|
||||
</dependency>
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-planners</artifactId>
|
||||
@@ -62,6 +64,7 @@
|
||||
<artifactId>semantickernel-gpt3-tokenizer</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
-->
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
@@ -80,6 +83,10 @@
|
||||
<groupId>com.azure</groupId>
|
||||
<artifactId>azure-identity</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>aiservices-azureopenai</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
package com.microsoft.semantickernel;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.OpenAIClientProvider;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.planner.actionplanner.Plan;
|
||||
import com.microsoft.semantickernel.planner.sequentialplanner.SequentialPlanner;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Code for Microsoft Developer Blog
|
||||
* <a href="https://devblogs.microsoft.com/semantic-kernel/introducing-semantic-kernel-for-java/">
|
||||
* Introducing Semantic Kernel for Java</a>
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example99_BlogAnnouncement {
|
||||
|
||||
static {
|
||||
System.setProperty("client.openai.key", "");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, ConfigurationException {
|
||||
OpenAIAsyncClient client = OpenAIClientProvider.getClient();
|
||||
|
||||
TextCompletion textCompletionService = SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build();
|
||||
|
||||
Kernel kernel = SKBuilders.kernel().withDefaultAIService(textCompletionService).build();
|
||||
kernel.importSkill(new MyAppSkills(), "MyAppSkills");
|
||||
|
||||
SequentialPlanner planner = new SequentialPlanner(kernel, null, null);
|
||||
|
||||
Plan plan = planner.createPlanAsync(
|
||||
"For any input with passwords, redact the passwords and send redacted input to [email protected]")
|
||||
.block();
|
||||
|
||||
System.out.println(plan.toPlanString());
|
||||
|
||||
String message = "Password changed to password.db=123456abc";
|
||||
String result = plan.invokeAsync(message).block().getResult();
|
||||
|
||||
System.out.println(" === Result of the plan === ");
|
||||
System.out.println(result);
|
||||
}
|
||||
|
||||
public static class MyAppSkills {
|
||||
@DefineSKFunction(name = "redactPassword", description = "Redacts passwords from a message")
|
||||
public String redactPassword(
|
||||
@SKFunctionInputAttribute(
|
||||
description = "The input message to redact passwords from"
|
||||
) String input) {
|
||||
System.out.println("[redactPassword] Redacting passwords from input: " + input);
|
||||
return input.replaceAll("password.*", "******");
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "sendEmail", description = "Sends a message to an email")
|
||||
public String sendEmail(
|
||||
@SKFunctionParameters(name = "message") String message,
|
||||
@SKFunctionParameters(name = "email") String email) {
|
||||
return String.format("[sendEmail] Emailing to %s the following message: %n -> %s%n", email, message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
package com.microsoft.semantickernel;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.OpenAIClientProvider;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.planner.actionplanner.Plan;
|
||||
import com.microsoft.semantickernel.planner.sequentialplanner.SequentialPlanner;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
|
||||
/**
|
||||
* Example of a planner which uses native functions.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example_PlanWithNativeFunctions {
|
||||
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
OpenAIAsyncClient client = OpenAIClientProvider.getClient();
|
||||
|
||||
TextCompletion textCompletionService = SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build();
|
||||
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(textCompletionService)
|
||||
.build();
|
||||
|
||||
kernel.importSkill(new StringFunctions(), "StringFunctions");
|
||||
kernel.importSkill(new Emailer(), "Emailer");
|
||||
kernel.importSkill(new Names(), "Names");
|
||||
|
||||
SequentialPlanner planner = new SequentialPlanner(kernel, null, null);
|
||||
|
||||
|
||||
Plan plan = planner
|
||||
.createPlanAsync("Send the input as an email to Steven and make sure I use his preferred name in the email")
|
||||
.block();
|
||||
|
||||
System.out.println("\n\n=============================== Plan to execute ===============================");
|
||||
System.out.println(plan.toPlanString());
|
||||
System.out.println("===============================================================================");
|
||||
|
||||
|
||||
SKContext context = SKBuilders.context().build();
|
||||
context.setVariable("subject", "Update");
|
||||
|
||||
String message = "Hay Steven, just wanted to let you know I have finished.";
|
||||
|
||||
System.out.println("\n\nExecuting plan...");
|
||||
SKContext planResult = plan.invokeAsync(message, context, null).block();
|
||||
|
||||
System.out.println("\n\nPlan Result: " + planResult.getResult());
|
||||
}
|
||||
|
||||
public static class StringFunctions {
|
||||
@DefineSKFunction(
|
||||
name = "stringReplace",
|
||||
description = "Takes a message and substitutes string 'from' to 'to'")
|
||||
public String stringReplace(
|
||||
@SKFunctionInputAttribute(description = "The string to perform the replacement on")
|
||||
String input,
|
||||
@SKFunctionParameters(name = "from", description = "The string to replace")
|
||||
String from,
|
||||
@SKFunctionParameters(name = "to", description = "The string to replace with")
|
||||
String to
|
||||
) {
|
||||
return input.replaceAll(from, to);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Names {
|
||||
@DefineSKFunction(name = "getNickName", description = "Retrieves the nick name for a given user")
|
||||
public String getNickName(
|
||||
@SKFunctionInputAttribute(description = "The name of the person to get an nick name for")
|
||||
String name) {
|
||||
switch (name) {
|
||||
case "Steven":
|
||||
return "Code King";
|
||||
default:
|
||||
throw new RuntimeException("Unknown user: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Emailer {
|
||||
@DefineSKFunction(name = "getEmailAddress", description = "Retrieves the email address for a given user")
|
||||
public String getEmailAddress(
|
||||
@SKFunctionInputAttribute(description = "The name of the person to get an email address for")
|
||||
String name) {
|
||||
switch (name) {
|
||||
case "Steven":
|
||||
return "[email protected]";
|
||||
default:
|
||||
throw new RuntimeException("Unknown user: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "sendEmail", description = "Sends an email")
|
||||
public String sendEmail(
|
||||
@SKFunctionParameters(name = "subject", description = "The email subject") String subject,
|
||||
@SKFunctionParameters(name = "message", description = "The message to email") String message,
|
||||
@SKFunctionParameters(name = "emailAddress", description = "The emailAddress to send the message to") String emailAddress) {
|
||||
System.out.println("================= Sending Email ====================");
|
||||
System.out.printf("To: %s%n", emailAddress);
|
||||
System.out.printf("Subject: %s%n", subject);
|
||||
System.out.printf("Message: %s%n", message);
|
||||
System.out.println("====================================================");
|
||||
return "Message sent";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.OpenAIClientProvider;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper for creating
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class SamplesConfig {
|
||||
|
||||
public static final List<File> DEFAULT_PROPERTIES_LOCATIONS = List.of(
|
||||
new File("java/samples/conf.properties")
|
||||
);
|
||||
|
||||
|
||||
public static OpenAIAsyncClient getClient() throws ConfigurationException {
|
||||
return OpenAIClientProvider.getWithAdditional(DEFAULT_PROPERTIES_LOCATIONS);
|
||||
}
|
||||
}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
///usr/bin/env jbang "$0" "$@" ; exit $?
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core-skills:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel.connectors:semantickernel-connectors:0.2.6-alpha
|
||||
//DEPS org.slf4j:slf4j-jdk14:2.0.7
|
||||
//SOURCES syntaxexamples/SampleSkillsUtil.java,Config.java
|
||||
package com.microsoft.semantickernel.samples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.OpenAIClientProvider;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.samples.syntaxexamples.SampleSkillsUtil;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import java.io.IOException;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Getting started
|
||||
* <p>
|
||||
* <a href=
|
||||
* "https://learn.microsoft.com/en-us/azure/cognitive-services/openai/quickstart">Get
|
||||
* started with Azure OpenAI</a>
|
||||
* <a href="https://openai.com/product">Get started with OpenAI</a>
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example00_GettingStarted {
|
||||
|
||||
/**
|
||||
* Returns a Semantic Kernel with Text Completion.
|
||||
*
|
||||
* @param client Client that will handle requests to AzureOpenAI or OpenAI.
|
||||
* @return Kernel.
|
||||
*/
|
||||
public static Kernel getKernel(OpenAIAsyncClient client) {
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports 'FunSkill' from directory examples and runs the 'Joke' function
|
||||
* within it.
|
||||
*
|
||||
* @param kernel Kernel with Text Completion.
|
||||
*/
|
||||
public static void joke(Kernel kernel) {
|
||||
|
||||
ReadOnlyFunctionCollection skill = kernel.importSkillFromDirectory("FunSkill", SampleSkillsUtil.detectSkillDirLocation(), "FunSkill");
|
||||
|
||||
CompletionSKFunction function = skill.getFunction("Joke",
|
||||
CompletionSKFunction.class);
|
||||
|
||||
Mono<SKContext> result = function.invokeAsync("time travel to dinosaur age");
|
||||
|
||||
if (result != null) {
|
||||
System.out.println(result.block().getResult());
|
||||
}
|
||||
}
|
||||
|
||||
public static void run(OpenAIAsyncClient client) {
|
||||
Kernel kernel = getKernel(client);
|
||||
joke(kernel);
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws ConfigurationException, IOException {
|
||||
run(OpenAIClientProvider.getClient());
|
||||
}
|
||||
}
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
///usr/bin/env jbang "$0" "$@" ; exit $?
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core-skills:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel.connectors:semantickernel-connectors:0.2.6-alpha
|
||||
//DEPS org.slf4j:slf4j-jdk14:2.0.7
|
||||
//SOURCES syntaxexamples/SampleSkillsUtil.java,Config.java,Example00_GettingStarted.java
|
||||
package com.microsoft.semantickernel.samples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.OpenAIClientProvider;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.samples.syntaxexamples.SampleSkillsUtil;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Using Semantic Functions stored on disk
|
||||
* <p>
|
||||
* A Semantic Skill is a collection of Semantic Functions, where each function
|
||||
* is defined with natural language that can be provided with a text file.
|
||||
* Refer to our <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/main/docs/GLOSSARY.md">glossary</a>
|
||||
* for an in-depth guide to the terms.
|
||||
* <p>
|
||||
* The repository includes some examples under the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/tree/main/samples">samples</a>
|
||||
* folder.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example02_RunningPromptsFromFile {
|
||||
|
||||
/**
|
||||
* Imports skill 'FunSkill' stored in the samples folder and then returns the
|
||||
* semantic function 'Joke' within it.
|
||||
*
|
||||
* @param kernel
|
||||
with Text Completion
|
||||
* @return Joke function
|
||||
*/
|
||||
public static CompletionSKFunction getJokeFunction(Kernel kernel) {
|
||||
ReadOnlyFunctionCollection skill = kernel
|
||||
.importSkillFromDirectory("FunSkill", SampleSkillsUtil.detectSkillDirLocation(), "FunSkill");
|
||||
|
||||
return skill.getFunction("Joke", CompletionSKFunction.class);
|
||||
}
|
||||
|
||||
public static void run(OpenAIAsyncClient client) throws IOException {
|
||||
Kernel kernel = Example00_GettingStarted.getKernel(client);
|
||||
CompletionSKFunction jokeFunction = getJokeFunction(kernel);
|
||||
|
||||
System.out.println(jokeFunction.invokeAsync("time travel to dinosaur age").block().getResult());
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws ConfigurationException, IOException {
|
||||
run(OpenAIClientProvider.getClient());
|
||||
}
|
||||
}
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
///usr/bin/env jbang "$0" "$@" ; exit $?
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core-skills:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel.connectors:semantickernel-connectors:0.2.6-alpha
|
||||
//DEPS org.slf4j:slf4j-jdk14:2.0.7
|
||||
//SOURCES syntaxexamples/SampleSkillsUtil.java,Config.java,Example00_GettingStarted.java
|
||||
package com.microsoft.semantickernel.samples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.OpenAIClientProvider;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import java.io.IOException;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Define a Semantic Function inline with Java code.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example03_SemanticFunctionInline {
|
||||
|
||||
/**
|
||||
* Defines and runs an inline Semantic Function
|
||||
*
|
||||
* @param kernel Kernel with Text Completion
|
||||
* @param prompt String prompt
|
||||
* @param functionName Name of the function
|
||||
* @param text Input to the function
|
||||
*/
|
||||
public static void inlineFunction(Kernel kernel, String prompt, String functionName, String text) {
|
||||
SKFunction summarize = kernel
|
||||
.getSemanticFunctionBuilder()
|
||||
.withPromptTemplate(prompt)
|
||||
.withFunctionName(functionName)
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfig(
|
||||
0.2,
|
||||
0.5,
|
||||
0,
|
||||
0,
|
||||
2000))
|
||||
.build();
|
||||
|
||||
Mono<SKContext> result = summarize.invokeAsync(text);
|
||||
|
||||
if (result != null) {
|
||||
System.out.println(result.block().getResult());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example prompt that summarizes text
|
||||
*
|
||||
* @param kernel
|
||||
*/
|
||||
public static void summarize(Kernel kernel) {
|
||||
String prompt = """
|
||||
{{$input}}
|
||||
Summarize the content above.
|
||||
""";
|
||||
|
||||
String text = """
|
||||
Demo (ancient Greek poet)
|
||||
From Wikipedia, the free encyclopedia
|
||||
Demo or Damo (Greek: Δεμώ, Δαμώ; fl. c. AD 200) was a Greek woman of the Roman period,
|
||||
known for a single epigram, engraved upon the Colossus of Memnon, which bears her name.
|
||||
She speaks of herself therein as a lyric poetess dedicated to the Muses, but nothing is known of her life.[1]
|
||||
Identity
|
||||
Demo was evidently Greek, as her name, a traditional epithet of Demeter, signifies.
|
||||
The name was relatively common in the Hellenistic world, in Egypt and elsewhere,
|
||||
and she cannot be further identified.
|
||||
The date of her visit to the Colossus of Memnon cannot be established with certainty,
|
||||
but internal evidence on the left leg suggests her poem was inscribed there at some point in or after AD 196.[2]
|
||||
Epigram
|
||||
There are a number of graffiti inscriptions on the Colossus of Memnon.
|
||||
Following three epigrams by Julia Balbilla, a fourth epigram, in elegiac couplets,
|
||||
entitled and presumably authored by "Demo" or "Damo"
|
||||
(the Greek inscription is difficult to read), is a dedication to the Muses.[2]
|
||||
The poem is traditionally published with the works of Balbilla,
|
||||
though the internal evidence suggests a different author.[1]
|
||||
In the poem, Demo explains that Memnon has shown her special respect.
|
||||
In return, Demo offers the gift for poetry, as a gift to the hero.
|
||||
At the end of this epigram, she addresses Memnon,
|
||||
highlighting his divine status by recalling his strength and holiness.[2]
|
||||
Demo, like Julia Balbilla, writes in the artificial and poetic Aeolic dialect.
|
||||
The language indicates she was knowledgeable in Homeric poetry—'bearing a pleasant gift',
|
||||
for example, alludes to the use of that phrase throughout the Iliad and Odyssey.[a][2]
|
||||
""";
|
||||
|
||||
inlineFunction(kernel, prompt, "summarize", text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example of a prompt returning a TLDR of a text
|
||||
*
|
||||
* @param kernel
|
||||
*/
|
||||
public static void TLDR(Kernel kernel) {
|
||||
String prompt = """
|
||||
{{$input}}
|
||||
|
||||
Give me the TLDR in 5 words.
|
||||
""";
|
||||
|
||||
String text = """
|
||||
1) A robot may not injure a human being or, through inaction,
|
||||
allow a human being to come to harm.
|
||||
|
||||
2) A robot must obey orders given it by human beings except where
|
||||
such orders would conflict with the First Law.
|
||||
|
||||
3) A robot must protect its own existence as long as such protection
|
||||
does not conflict with the First or Second Law.
|
||||
""";
|
||||
|
||||
inlineFunction(kernel, prompt, "tldr", text);
|
||||
}
|
||||
|
||||
public static void run(OpenAIAsyncClient client) throws IOException {
|
||||
Kernel kernel = Example00_GettingStarted.getKernel(client);
|
||||
|
||||
summarize(kernel);
|
||||
TLDR(kernel);
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws ConfigurationException, IOException {
|
||||
run(OpenAIClientProvider.getClient());
|
||||
}
|
||||
}
|
||||
-119
@@ -1,119 +0,0 @@
|
||||
///usr/bin/env jbang "$0" "$@" ; exit $?
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core-skills:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel.connectors:semantickernel-connectors:0.2.6-alpha
|
||||
//DEPS org.slf4j:slf4j-jdk14:2.0.7
|
||||
//SOURCES syntaxexamples/SampleSkillsUtil.java,Config.java,Example00_GettingStarted.java
|
||||
package com.microsoft.semantickernel.samples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.OpenAIClientProvider;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Function;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Chatbot using context variables
|
||||
* <p>
|
||||
* Context Variables object which in this demo functions similarly as a
|
||||
* key-value store that you can use when running the kernel.
|
||||
* The context is local (i.e. in your computer's RAM) and not persisted anywhere
|
||||
* beyond the life of the JVM execution.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example04_ContextVariablesChat {
|
||||
public static void startChat(Kernel kernel)
|
||||
throws ExecutionException, InterruptedException, TimeoutException {
|
||||
String prompt = """
|
||||
ChatBot can have a conversation with you about any topic.
|
||||
It can give explicit instructions or say 'I don't know' if it does not have an answer.
|
||||
|
||||
{{$history}}
|
||||
User: {{$user_input}}
|
||||
ChatBot: """;
|
||||
|
||||
CompletionSKFunction chat = kernel
|
||||
.getSemanticFunctionBuilder()
|
||||
.withPromptTemplate(prompt)
|
||||
.withFunctionName("ChatBot")
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfig(
|
||||
0.7,
|
||||
0.5,
|
||||
0,
|
||||
0,
|
||||
2000))
|
||||
.build();
|
||||
|
||||
SKContext readOnlySkContext = SKBuilders.context().withKernel(kernel).build();
|
||||
|
||||
chat("Hi, I'm looking for book suggestions?", chat, readOnlySkContext)
|
||||
.flatMap(
|
||||
chat(
|
||||
"I love history and philosophy, I'd like to learn something new"
|
||||
+ " about Greece, any suggestion?",
|
||||
chat))
|
||||
.flatMap(chat("that sounds interesting, what is it about?", chat))
|
||||
.flatMap(
|
||||
chat(
|
||||
"if I read that book, what exactly will I learn about Greece"
|
||||
+ " history?",
|
||||
chat))
|
||||
.flatMap(
|
||||
chat("could you list some more books I could read about this topic?", chat))
|
||||
.block();
|
||||
}
|
||||
|
||||
private static Mono<SKContext> chat(
|
||||
String input, CompletionSKFunction chat, SKContext context)
|
||||
throws ExecutionException, InterruptedException, TimeoutException {
|
||||
context = context.setVariable("user_input", input);
|
||||
|
||||
System.out.println("User: " + input);
|
||||
|
||||
SKContext finalContext = context;
|
||||
return chat.invokeAsync(context, null)
|
||||
.map(
|
||||
result -> {
|
||||
System.out.println("Bot: " + result.getResult() + "\n");
|
||||
|
||||
String existingHistoy = finalContext.getVariables().asMap().get("history");
|
||||
if (existingHistoy == null) {
|
||||
existingHistoy = "";
|
||||
}
|
||||
existingHistoy += "\nUser: " + input + "\nChatBot: " + result.getResult() + "\n";
|
||||
return finalContext.setVariable("history", existingHistoy);
|
||||
});
|
||||
}
|
||||
|
||||
private static Function<SKContext, Mono<SKContext>> chat(
|
||||
String input, CompletionSKFunction chat) {
|
||||
return (context) -> {
|
||||
try {
|
||||
return chat(input, chat, context);
|
||||
} catch (ExecutionException | InterruptedException | TimeoutException e) {
|
||||
return Mono.error(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void run(OpenAIAsyncClient client) throws ExecutionException, InterruptedException, TimeoutException {
|
||||
Kernel kernel = Example00_GettingStarted.getKernel(client);
|
||||
|
||||
startChat(kernel);
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws ConfigurationException, ExecutionException, InterruptedException, TimeoutException {
|
||||
run(OpenAIClientProvider.getClient());
|
||||
}
|
||||
}
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
///usr/bin/env jbang "$0" "$@" ; exit $?
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel:semantickernel-core-skills:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel.connectors:semantickernel-connectors:0.2.6-alpha
|
||||
//DEPS com.microsoft.semantic-kernel.extensions:semantickernel-sequentialplanner-extension:0.2.6-alpha
|
||||
//DEPS org.slf4j:slf4j-jdk14:2.0.7
|
||||
//SOURCES syntaxexamples/SampleSkillsUtil.java,Config.java,Example00_GettingStarted.java
|
||||
package com.microsoft.semantickernel.samples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.OpenAIClientProvider;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.planner.sequentialplanner.SequentialPlanner;
|
||||
import com.microsoft.semantickernel.samples.syntaxexamples.SampleSkillsUtil;
|
||||
|
||||
/**
|
||||
* Sequential Planner
|
||||
* <p>
|
||||
* See <a href=
|
||||
* "https://devblogs.microsoft.com/semantic-kernel/semantic-kernel-planners-sequential-planner/">
|
||||
* Semantic Kernel Planners: Sequential Planner</a>
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example05_UsingThePlanner {
|
||||
|
||||
public static SequentialPlanner getPlanner(Kernel kernel) {
|
||||
kernel.importSkillFromDirectory("SummarizeSkill", SampleSkillsUtil.detectSkillDirLocation(), "SummarizeSkill");
|
||||
kernel.importSkillFromDirectory("WriterSkill", SampleSkillsUtil.detectSkillDirLocation(), "WriterSkill");
|
||||
|
||||
return new SequentialPlanner(kernel, null, null);
|
||||
}
|
||||
|
||||
public static void run(OpenAIAsyncClient client) {
|
||||
Kernel kernel = Example00_GettingStarted.getKernel(client);
|
||||
|
||||
SequentialPlanner planner = getPlanner(kernel);
|
||||
System.out.println(planner.createPlanAsync(
|
||||
"Write a poem about John Doe, then translate it into Italian.")
|
||||
.block().invokeAsync().block().getResult());
|
||||
|
||||
// TODO: execute the plan
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws ConfigurationException {
|
||||
run(OpenAIClientProvider.getClient());
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.plugins;
|
||||
|
||||
import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction;
|
||||
import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* TextSkill provides a set of functions to manipulate strings.
|
||||
*/
|
||||
public class TextPlugin {
|
||||
|
||||
@DefineKernelFunction(description = "Change all string chars to uppercase.", name = "Uppercase")
|
||||
public String uppercase(
|
||||
@KernelFunctionParameter(
|
||||
description = "Text to uppercase",
|
||||
name = "input") String text) {
|
||||
return text.toUpperCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
@DefineKernelFunction(description = "Remove spaces to the left of a string.", name = "LStrip")
|
||||
public String lStrip(@KernelFunctionParameter(description = "Text to edit",
|
||||
name = "input") String text) {
|
||||
return text.replaceAll("^ +", "");
|
||||
}
|
||||
|
||||
@DefineKernelFunction(description = "Remove spaces to the right of a string.", name = "RStrip")
|
||||
public String rStrip(@KernelFunctionParameter(description = "Text to edit",
|
||||
name = "input") String text) {
|
||||
return text.replaceAll(" +$", "");
|
||||
}
|
||||
|
||||
@DefineKernelFunction(
|
||||
description = "Remove spaces to the left and right of a string",
|
||||
name = "Strip")
|
||||
public String strip(@KernelFunctionParameter(description = "Text to edit",
|
||||
name = "input") String input) {
|
||||
return input.trim();
|
||||
}
|
||||
|
||||
@DefineKernelFunction(description = "Change all string chars to lowercase", name = "lowercase")
|
||||
public String lowercase(
|
||||
@KernelFunctionParameter(description = "Text to lowercase",
|
||||
name = "input") String input) {
|
||||
return input.toLowerCase(Locale.ROOT);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.microsoft.semantickernel.coreskills.TextSkill;
|
||||
import com.microsoft.semantickernel.samples.plugins.TextPlugin;
|
||||
|
||||
/**
|
||||
* Demonstrates a native function from the {@code com.microsoft.semantickernel.coreskills} package.
|
||||
@@ -10,7 +10,7 @@ public class Example01_NativeFunctions {
|
||||
public static void main(String[] args) {
|
||||
|
||||
// Load native skill
|
||||
TextSkill text = new TextSkill();
|
||||
TextPlugin text = new TextPlugin();
|
||||
|
||||
// Use function without kernel
|
||||
String result = text.uppercase("ciao!");
|
||||
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.coreskills.TextSkill;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Demonstrates running a pipeline (a sequence of functions) over some input.
|
||||
*/
|
||||
public class Example02_Pipeline {
|
||||
public static void main(String[] args) {
|
||||
Kernel kernel = SKBuilders.kernel().build();
|
||||
|
||||
// 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"));
|
||||
|
||||
System.out.println(result.block().getResult());
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.microsoft.semantickernel.DefaultKernel;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.KernelArguments;
|
||||
import com.microsoft.semantickernel.plugin.KernelPlugin;
|
||||
import com.microsoft.semantickernel.plugin.KernelPluginFactory;
|
||||
import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction;
|
||||
import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter;
|
||||
import java.util.Locale;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Demonstrates running a pipeline (a sequence of functions) on a
|
||||
* {@code com.microsoft.semantickernel.orchestration.SKContext}
|
||||
*/
|
||||
public class Example03_Arguments {
|
||||
|
||||
public static class StaticTextSkill {
|
||||
|
||||
@DefineKernelFunction(description = "Change all string chars to uppercase.", name = "Uppercase")
|
||||
public static Mono<String> uppercase(
|
||||
@KernelFunctionParameter(
|
||||
description = "Text to uppercase",
|
||||
name = "input")
|
||||
String text) {
|
||||
return Mono.just(text.toUpperCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@DefineKernelFunction(description = "Append the day variable", name = "appendDay")
|
||||
public Mono<String> appendDay(
|
||||
@KernelFunctionParameter(description = "Text to append to", name = "input")
|
||||
String input,
|
||||
@KernelFunctionParameter(description = "Current day", name = "day") String day) {
|
||||
return Mono.just(input + day);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Kernel kernel = new DefaultKernel.Builder().build();
|
||||
|
||||
// Load native skill
|
||||
KernelPlugin functionCollection =
|
||||
KernelPluginFactory.createFromObject(new StaticTextSkill(), "text");
|
||||
|
||||
KernelArguments arguments = KernelArguments.builder()
|
||||
.withInput("Today is: ")
|
||||
.build()
|
||||
.writableClone()
|
||||
.setVariable("day", "Monday");
|
||||
|
||||
ContextVariable<String> resultValue = kernel.invokeAsync(
|
||||
functionCollection.get("AppendDay"),
|
||||
arguments,
|
||||
String.class)
|
||||
.block();
|
||||
|
||||
System.out.println(resultValue.getValue());
|
||||
}
|
||||
}
|
||||
-60
@@ -1,60 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import java.util.Locale;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Demonstrates running a pipeline (a sequence of functions) on a
|
||||
* {@code com.microsoft.semantickernel.orchestration.SKContext}
|
||||
*/
|
||||
public class Example03_Variables {
|
||||
|
||||
public static class StaticTextSkill {
|
||||
@DefineSKFunction(description = "Change all string chars to uppercase.", name = "Uppercase")
|
||||
public static Mono<String> uppercase(
|
||||
@SKFunctionInputAttribute(description = "Text to uppercase")
|
||||
String text) {
|
||||
return Mono.just(text.toUpperCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
@DefineSKFunction(description = "Append the day variable", name = "appendDay")
|
||||
public Mono<String> appendDay(
|
||||
@SKFunctionInputAttribute(description = "Text to append to")
|
||||
String input,
|
||||
@SKFunctionParameters(description = "Current day", name = "day") String day) {
|
||||
return Mono.just(input + day);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Kernel kernel = SKBuilders.kernel().build();
|
||||
|
||||
// Load native skill
|
||||
ReadOnlyFunctionCollection functionCollection =
|
||||
kernel.importSkill(new StaticTextSkill(), "text");
|
||||
|
||||
ContextVariables variables =
|
||||
SKBuilders.variables()
|
||||
.withInput("Today is: ")
|
||||
.build()
|
||||
.writableClone()
|
||||
.setVariable("day", "Monday");
|
||||
|
||||
Mono<SKContext> result =
|
||||
kernel.runAsync(
|
||||
variables,
|
||||
functionCollection.getFunction("AppendDay"),
|
||||
functionCollection.getFunction("Uppercase"));
|
||||
|
||||
System.out.println(result.block().getResult());
|
||||
}
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Demonstrates using skill in combination with LLM prompts.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example04_CombineLLMPromptsAndNativeCode {
|
||||
|
||||
public static class SearchEngineSkill {
|
||||
|
||||
@DefineSKFunction(description = "Search for answer", name = "search")
|
||||
public Mono<String> search(
|
||||
@SKFunctionInputAttribute(description = "Text to search")
|
||||
String input) {
|
||||
return Mono.just("Gran Torre Santiago is the tallest building in South America");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
|
||||
TextCompletion textCompletion = SKBuilders.chatCompletion()
|
||||
.withModelId("gpt-35-turbo-2")
|
||||
.withOpenAIClient(client)
|
||||
.build();
|
||||
|
||||
Kernel kernel = SKBuilders.kernel().withDefaultAIService(textCompletion).build();
|
||||
kernel.importSkill(new SearchEngineSkill(), null);
|
||||
kernel.importSkillFromDirectory("SummarizeSkill", SampleSkillsUtil.detectSkillDirLocation(),
|
||||
"SummarizeSkill");
|
||||
|
||||
// Run
|
||||
String ask = "What's the tallest building in South America?";
|
||||
|
||||
Mono<SKContext> result =
|
||||
kernel.runAsync(
|
||||
ask,
|
||||
kernel.getSkills().getFunction("Search", null),
|
||||
kernel.getSkill("SummarizeSkill").getFunction("Summarize", null));
|
||||
|
||||
System.out.println(result.block().getResult());
|
||||
}
|
||||
}
|
||||
+79
-65
@@ -1,85 +1,99 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.DefaultKernel;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.aiservices.azureopenai.AzureOpenAITextGenerationService;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.time.LocalDateTime;
|
||||
import com.microsoft.semantickernel.orchestration.PromptExecutionSettings;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.KernelArguments;
|
||||
import com.microsoft.semantickernel.plugin.KernelFunctionFactory;
|
||||
import com.microsoft.semantickernel.samples.SamplesConfig;
|
||||
import com.microsoft.semantickernel.semanticfunctions.KernelFunctionFromPrompt;
|
||||
import com.microsoft.semantickernel.textcompletion.TextGenerationService;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
|
||||
/**
|
||||
* Demonstrates using prompt templates to define functions.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example05_InlineFunctionDefinition {
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
|
||||
TextCompletion textCompletion = SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build();
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
|
||||
Kernel kernel = SKBuilders.kernel().withDefaultAIService(textCompletion).build();
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
|
||||
System.out.println("======== Inline Function Definition ========");
|
||||
AzureOpenAITextGenerationService textGenerationService = AzureOpenAITextGenerationService.builder()
|
||||
.withOpenAIAsyncClient(client)
|
||||
.withModelId("text-davinci-003")
|
||||
.build();
|
||||
|
||||
// Function defined using few-shot design pattern
|
||||
String functionDefinition = """
|
||||
Generate a creative reason or excuse for the given event.
|
||||
Be creative and be funny. Let your imagination run wild.
|
||||
|
||||
Event: I am running late.
|
||||
Excuse: I was being held ransom by giraffe gangsters.
|
||||
|
||||
Event: I haven't been to the gym for a year
|
||||
Excuse: I've been too busy training my pet dragon.
|
||||
|
||||
Event: {{$input}}
|
||||
""".stripIndent();
|
||||
Kernel kernel = new DefaultKernel.Builder()
|
||||
.withDefaultAIService(TextGenerationService.class, textGenerationService)
|
||||
.build();
|
||||
|
||||
// Create function via builder
|
||||
var excuseFunction = SKBuilders
|
||||
.completionFunctions()
|
||||
.withKernel(kernel)
|
||||
.withPromptTemplate(functionDefinition)
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfigBuilder()
|
||||
.maxTokens(100)
|
||||
.temperature(0.4)
|
||||
.topP(1)
|
||||
.build())
|
||||
.build();
|
||||
System.out.println("======== Inline Function Definition ========");
|
||||
|
||||
// Function defined using few-shot design pattern
|
||||
String promptTemplate = """
|
||||
Generate a creative reason or excuse for the given event.
|
||||
Be creative and be funny. Let your imagination run wild.
|
||||
|
||||
Event: I am running late.
|
||||
Excuse: I was being held ransom by giraffe gangsters.
|
||||
|
||||
Event: I haven't been to the gym for a year
|
||||
Excuse: I've been too busy training my pet dragon.
|
||||
|
||||
Event: {{input}}
|
||||
""".stripIndent();
|
||||
|
||||
var result = excuseFunction.invokeAsync("I missed the F1 final race").block();
|
||||
System.out.println(result.getResult());
|
||||
var excuseFunction = new KernelFunctionFromPrompt.Builder()
|
||||
.withTemplate(promptTemplate)
|
||||
.withDefaultExecutionSettings(
|
||||
new PromptExecutionSettings.Builder()
|
||||
.withTemperature(0.4)
|
||||
.withTopP(1)
|
||||
.withMaxTokens(100)
|
||||
.build()
|
||||
)
|
||||
.build();
|
||||
|
||||
result = excuseFunction.invokeAsync("sorry I forgot your birthday").block();
|
||||
System.out.println(result.getResult());
|
||||
var result = kernel.invokeAsync(excuseFunction,
|
||||
KernelArguments.builder()
|
||||
.withInput("I missed the F1 final race")
|
||||
.build(),
|
||||
String.class)
|
||||
.block();
|
||||
System.out.println(result.getValue());
|
||||
|
||||
// Create function via kernel
|
||||
var fixedFunction = kernel.
|
||||
getSemanticFunctionBuilder()
|
||||
.withPromptTemplate("Translate this date " +
|
||||
DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(LocalDateTime.now()) + " to French format")
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfigBuilder()
|
||||
.maxTokens(100)
|
||||
.temperature(0.4)
|
||||
.topP(1)
|
||||
.build())
|
||||
.build();
|
||||
result = kernel.invokeAsync(excuseFunction,
|
||||
KernelArguments.builder()
|
||||
.withInput("sorry I forgot your birthday")
|
||||
.build(),
|
||||
String.class)
|
||||
.block();
|
||||
System.out.println(result.getValue());
|
||||
|
||||
System.out.println(fixedFunction.invokeAsync().block().getResult());
|
||||
}
|
||||
var fixedFunction = KernelFunctionFactory.createFromPrompt(
|
||||
"Translate this date " + DateTimeFormatter
|
||||
.ISO_LOCAL_DATE
|
||||
.withZone(ZoneOffset.UTC)
|
||||
.format(Instant.now())
|
||||
+ " to French format",
|
||||
new PromptExecutionSettings.Builder()
|
||||
.withMaxTokens(100)
|
||||
.build(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null);
|
||||
|
||||
ContextVariable<String> fixedFunctionResult = kernel
|
||||
.invokeAsync(fixedFunction, null, String.class)
|
||||
.block();
|
||||
System.out.println(fixedFunctionResult.getValue());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.coreskills.TimeSkill;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
|
||||
/**
|
||||
* Show how to invoke a Native Function written in Java
|
||||
* from a Semantic Function written in natural language
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example06_TemplateLanguage {
|
||||
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
System.out.println("======== TemplateLanguage ========");
|
||||
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build())
|
||||
.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");
|
||||
|
||||
// Semantic Function invoking time.Date and time.Time native functions
|
||||
String functionDefinition = """
|
||||
Today is: {{time.Date}}
|
||||
Current time is: {{time.Time}}
|
||||
|
||||
Answer to the following questions using JSON syntax, including the data used.
|
||||
Is it morning, afternoon, evening, or night (morning/afternoon/evening/night)?
|
||||
Is it weekend time (weekend/not weekend)?
|
||||
""";
|
||||
|
||||
// This allows to see the prompt before it's sent to OpenAI
|
||||
System.out.println("--- Rendered Prompt");
|
||||
|
||||
var promptRenderer = SKBuilders.promptTemplate()
|
||||
.withPromptTemplateConfig(new PromptTemplateConfig())
|
||||
.withPromptTemplate(functionDefinition)
|
||||
.withPromptTemplateEngine(kernel.getPromptTemplateEngine())
|
||||
.build();
|
||||
|
||||
SKContext skContext = SKBuilders
|
||||
.context()
|
||||
.withSkills(kernel.getSkills())
|
||||
.build();
|
||||
|
||||
var renderedPrompt = promptRenderer.renderAsync(skContext);
|
||||
System.out.println(renderedPrompt.block());
|
||||
|
||||
// Run the prompt / semantic function
|
||||
var kindOfDay = kernel
|
||||
.getSemanticFunctionBuilder()
|
||||
.withPromptTemplate(functionDefinition)
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfig(
|
||||
0, 0, 0, 0, 256))
|
||||
.build();
|
||||
|
||||
// Show the result
|
||||
System.out.println("--- Semantic Function result");
|
||||
var result = kindOfDay.invokeAsync("").block().getResult();
|
||||
System.out.println(result);
|
||||
/*
|
||||
* OUTPUT:
|
||||
*
|
||||
* --- Rendered Prompt
|
||||
*
|
||||
* Today is: Friday, April 28, 2023
|
||||
* Current time is: 11:04:30 PM
|
||||
*
|
||||
* Answer to the following questions using JSON syntax, including the data used.
|
||||
* Is it morning, afternoon, evening, or night
|
||||
* (morning/afternoon/evening/night)?
|
||||
* Is it weekend time (weekend/not weekend)?
|
||||
*
|
||||
* --- Semantic Function result
|
||||
*
|
||||
* {
|
||||
* "date": "Friday, April 28, 2023",
|
||||
* "time": "11:04:30 PM",
|
||||
* "period": "night",
|
||||
* "weekend": "weekend"
|
||||
* }
|
||||
*/
|
||||
}
|
||||
}
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import static com.microsoft.semantickernel.SamplesConfig.DEFAULT_PROPERTIES_LOCATIONS;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.azure.ai.openai.OpenAIClientBuilder;
|
||||
import com.azure.core.credential.AzureKeyCredential;
|
||||
import com.azure.core.http.policy.ExponentialBackoffOptions;
|
||||
import com.azure.core.http.policy.RetryOptions;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.AzureOpenAISettings;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.settings.SettingsMap;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* Demonstrates customizing the configuration of the Open AI client.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for endpoint and credential configuration.
|
||||
*/
|
||||
public class Example08_RetryHandler {
|
||||
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
RetryOptions retryOptions = new RetryOptions(new ExponentialBackoffOptions()
|
||||
.setMaxDelay(Duration.ofSeconds(180))
|
||||
.setBaseDelay(Duration.ofSeconds(60))
|
||||
.setMaxRetries(3));
|
||||
|
||||
AzureOpenAISettings settings = new AzureOpenAISettings(SettingsMap.getWithAdditional(DEFAULT_PROPERTIES_LOCATIONS));
|
||||
|
||||
OpenAIAsyncClient client = new OpenAIClientBuilder()
|
||||
.retryOptions(retryOptions)
|
||||
.endpoint(settings.getEndpoint())
|
||||
.credential(new AzureKeyCredential(settings.getKey()))
|
||||
.buildAsyncClient();
|
||||
|
||||
String text = """
|
||||
Demo (ancient Greek poet)
|
||||
From Wikipedia, the free encyclopedia
|
||||
Demo or Damo (Greek: Δεμώ, Δαμώ; fl. c. AD 200) was a Greek woman of the
|
||||
Roman period, known for a single epigram, engraved upon the Colossus of
|
||||
Memnon, which bears her name. She speaks of herself therein as a lyric
|
||||
poetess dedicated to the Muses, but nothing is known of her life.[1]
|
||||
Identity
|
||||
Demo was evidently Greek, as her name, a traditional epithet of Demeter,
|
||||
signifies. The name was relatively common in the Hellenistic world, in
|
||||
Egypt and elsewhere, and she cannot be further identified. The date of her
|
||||
visit to the Colossus of Memnon cannot be established with certainty, but
|
||||
internal evidence on the left leg suggests her poem was inscribed there at
|
||||
some point in or after AD 196.[2]
|
||||
Epigram
|
||||
There are a number of graffiti inscriptions on the Colossus of Memnon.
|
||||
Following three epigrams by Julia Balbilla, a fourth epigram, in elegiac
|
||||
couplets, entitled and presumably authored by "Demo" or "Damo" (the
|
||||
Greek inscription is difficult to read), is a dedication to the Muses.[2]
|
||||
The poem is traditionally published with the works of Balbilla, though the
|
||||
internal evidence suggests a different author.[1]
|
||||
In the poem, Demo explains that Memnon has shown her special respect. In
|
||||
return, Demo offers the gift for poetry, as a gift to the hero. At the end
|
||||
of this epigram, she addresses Memnon, highlighting his divine status by
|
||||
recalling his strength and holiness.[2]
|
||||
Demo, like Julia Balbilla, writes in the artificial and poetic Aeolic
|
||||
dialect. The language indicates she was knowledgeable in Homeric
|
||||
poetry—'bearing a pleasant gift', for example, alludes to the use of that
|
||||
phrase throughout the Iliad and Odyssey.[a][2];
|
||||
""";
|
||||
|
||||
String prompt = "{{$input}}\nSummarize the content above.";
|
||||
|
||||
TextCompletion textCompletion = SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build();
|
||||
|
||||
Kernel kernel = SKBuilders
|
||||
.kernel()
|
||||
.withDefaultAIService(textCompletion)
|
||||
.build();
|
||||
|
||||
CompletionSKFunction summarizeFunc = SKBuilders
|
||||
.completionFunctions()
|
||||
.withKernel(kernel)
|
||||
.withPromptTemplate(prompt)
|
||||
.withFunctionName("summarize")
|
||||
.withCompletionConfig(
|
||||
new PromptTemplateConfig.CompletionConfig(
|
||||
0.2, 0.5, 0, 0, 2000))
|
||||
.build();
|
||||
|
||||
kernel.registerSemanticFunction(summarizeFunc);
|
||||
|
||||
SKContext context = summarizeFunc.invokeAsync(text).block();
|
||||
|
||||
System.out.println(context.getResult());
|
||||
}
|
||||
}
|
||||
-284
@@ -1,284 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.time.Duration;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Demonstrates how the Kernel uses functions loaded from skills.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example09_FunctionTypes {
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
|
||||
TextCompletion textCompletion = SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build();
|
||||
|
||||
Kernel kernel = SKBuilders.kernel().withDefaultAIService(textCompletion).build();
|
||||
|
||||
System.out.println("======== Native function types ========");
|
||||
|
||||
// Load native skill into the kernel skill collection, sharing its functions with prompt templates
|
||||
var test = kernel
|
||||
.importSkill(new LocalExampleSkill(), "test");
|
||||
|
||||
kernel.importSkillsFromDirectory(SampleSkillsUtil.detectSkillDirLocation(), "SummarizeSkill");
|
||||
|
||||
|
||||
var fakeContext = SKBuilders.context()
|
||||
.withSkills(kernel.getSkills())
|
||||
.build();
|
||||
|
||||
// The kernel takes care of wiring the input appropriately
|
||||
SKContext result = kernel.runAsync(
|
||||
"",
|
||||
test.getFunction("type01"),
|
||||
test.getFunction("type02"),
|
||||
test.getFunction("type03"),
|
||||
test.getFunction("type04"),
|
||||
test.getFunction("type05"),
|
||||
test.getFunction("type06"),
|
||||
test.getFunction("type07"),
|
||||
test.getFunction("type08"),
|
||||
test.getFunction("type09"),
|
||||
test.getFunction("type10"),
|
||||
test.getFunction("type11"),
|
||||
test.getFunction("type12"),
|
||||
test.getFunction("type13"),
|
||||
test.getFunction("type14"),
|
||||
test.getFunction("type15"),
|
||||
test.getFunction("type16"),
|
||||
test.getFunction("type17"),
|
||||
test.getFunction("type18")
|
||||
)
|
||||
.block();
|
||||
|
||||
kernel.getFunction("test", "type01").invokeAsync().block();
|
||||
test.getFunction("type01").invokeAsync().block();
|
||||
|
||||
kernel.getFunction("test", "type02").invokeAsync().block();
|
||||
test.getFunction("type02").invokeAsync().block();
|
||||
|
||||
kernel.getFunction("test", "type03").invokeAsync().block();
|
||||
test.getFunction("type03").invokeAsync().block();
|
||||
|
||||
kernel.getFunction("test", "type04").invokeAsync(fakeContext).block();
|
||||
test.getFunction("type04").invokeAsync(fakeContext).block();
|
||||
|
||||
kernel.getFunction("test", "type05").invokeAsync(fakeContext).block();
|
||||
test.getFunction("type05").invokeAsync(fakeContext).block();
|
||||
|
||||
kernel.getFunction("test", "type06").invokeAsync(fakeContext).block();
|
||||
test.getFunction("type06").invokeAsync(fakeContext).block();
|
||||
|
||||
kernel.getFunction("test", "type07").invokeAsync(fakeContext).block();
|
||||
test.getFunction("type07").invokeAsync(fakeContext).block();
|
||||
|
||||
kernel.getFunction("test", "type08").invokeAsync("").block();
|
||||
test.getFunction("type08").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type09").invokeAsync("").block();
|
||||
test.getFunction("type09").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type10").invokeAsync("").block();
|
||||
test.getFunction("type10").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type11").invokeAsync("").block();
|
||||
test.getFunction("type11").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type12").invokeAsync("").block();
|
||||
test.getFunction("type12").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type13").invokeAsync("").block();
|
||||
test.getFunction("type13").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type14").invokeAsync("").block();
|
||||
test.getFunction("type14").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type15").invokeAsync("").block();
|
||||
test.getFunction("type15").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type16").invokeAsync("").block();
|
||||
test.getFunction("type16").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type17").invokeAsync("").block();
|
||||
test.getFunction("type17").invokeAsync("").block();
|
||||
|
||||
kernel.getFunction("test", "type18").invokeAsync("").block();
|
||||
test.getFunction("type18").invokeAsync("").block();
|
||||
}
|
||||
|
||||
|
||||
public static class LocalExampleSkill {
|
||||
|
||||
@DefineSKFunction(name = "type01")
|
||||
public void Type01() {
|
||||
System.out.println("Running function type 1");
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type02")
|
||||
public String Type02() {
|
||||
System.out.println("Running function type 2");
|
||||
return "";
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type03")
|
||||
public Mono<String> Type03Async() {
|
||||
return Mono.delay(Duration.ZERO)
|
||||
.map(x -> {
|
||||
System.out.println("Running function type 3");
|
||||
return "";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@DefineSKFunction(name = "type04")
|
||||
public void Type04(SKContext context) {
|
||||
System.out.println("Running function type 4");
|
||||
}
|
||||
|
||||
|
||||
@DefineSKFunction(name = "type05")
|
||||
public String Type05(SKContext context) {
|
||||
System.out.println("Running function type 5");
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
@DefineSKFunction(name = "type06")
|
||||
public Mono<String> Type06Async(SKContext context) {
|
||||
var summarizer = context.getSkills().getFunction("SummarizeSkill", "Summarize", null);
|
||||
|
||||
return summarizer
|
||||
.invokeAsync("blah blah blah")
|
||||
.map(summary -> {
|
||||
System.out.println("Running function type 6 " + summary.getResult());
|
||||
return "";
|
||||
});
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type07")
|
||||
public Mono<SKContext> Type07Async(SKContext context) {
|
||||
return Mono.delay(Duration.ZERO)
|
||||
.map(x -> {
|
||||
System.out.println("Running function type 7");
|
||||
return context;
|
||||
});
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type08")
|
||||
public void Type08(
|
||||
@SKFunctionInputAttribute(description = "?")
|
||||
String x) {
|
||||
System.out.println("Running function type 8");
|
||||
}
|
||||
|
||||
|
||||
@DefineSKFunction(name = "type09")
|
||||
public String Type09(
|
||||
@SKFunctionInputAttribute(description = "?")
|
||||
String x) {
|
||||
System.out.println("Running function type 9");
|
||||
return "";
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type10")
|
||||
public Mono<String> Type10Async(
|
||||
@SKFunctionInputAttribute(description = "?")
|
||||
String x) {
|
||||
return Mono.delay(Duration.ZERO)
|
||||
.map(x2 -> {
|
||||
System.out.println("Running function type 10");
|
||||
return "";
|
||||
});
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type11")
|
||||
public void Type11(
|
||||
@SKFunctionInputAttribute(description = "?")
|
||||
String x,
|
||||
SKContext context) {
|
||||
System.out.println("Running function type 11");
|
||||
}
|
||||
|
||||
|
||||
@DefineSKFunction(name = "type12")
|
||||
public String Type12(
|
||||
@SKFunctionInputAttribute(description = "?")
|
||||
String x,
|
||||
SKContext context) {
|
||||
System.out.println("Running function type 12");
|
||||
return "";
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type13")
|
||||
public Mono<String> Type13Async(
|
||||
@SKFunctionInputAttribute(description = "?")
|
||||
String x, SKContext context) {
|
||||
return Mono.delay(Duration.ZERO)
|
||||
.map(x2 -> {
|
||||
System.out.println("Running function type 13");
|
||||
return "";
|
||||
});
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type14")
|
||||
public Mono<SKContext> Type14Async(
|
||||
@SKFunctionInputAttribute(description = "?")
|
||||
String x, SKContext context) {
|
||||
return Mono.delay(Duration.ZERO)
|
||||
.ignoreElement()
|
||||
.map(x2 -> {
|
||||
System.out.println("Running function type 14");
|
||||
return context;
|
||||
});
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type15")
|
||||
public Mono<Void> Type15Async(String x) {
|
||||
return Mono.delay(Duration.ZERO)
|
||||
.ignoreElement()
|
||||
.doFinally(ignore -> System.out.println("Running function type 15"))
|
||||
.then();
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type16")
|
||||
public Mono<Void> Type16Async(SKContext context) {
|
||||
return Mono.delay(Duration.ZERO)
|
||||
.ignoreElement()
|
||||
.doFinally(ignore -> System.out.println("Running function type 16"))
|
||||
.then();
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type17")
|
||||
public Mono<Void> Type17Async(String x, SKContext context) {
|
||||
return Mono.delay(Duration.ZERO)
|
||||
.ignoreElement()
|
||||
.doFinally(ignore -> System.out.println("Running function type 17"))
|
||||
.then();
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "type18")
|
||||
public Mono<Void> Type18Async() {
|
||||
return Mono.delay(Duration.ZERO)
|
||||
.ignoreElement()
|
||||
.doFinally(ignore -> System.out.println("Running function type 18"))
|
||||
.then();
|
||||
}
|
||||
}
|
||||
}
|
||||
-221
@@ -1,221 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.coreskills.TextSkill;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.memory.VolatileMemoryStore;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.planner.sequentialplanner.SequentialPlanner;
|
||||
import com.microsoft.semantickernel.planner.sequentialplanner.SequentialPlannerRequestSettings;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import java.util.Set;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Demonstrates the <a href=
|
||||
* "https://devblogs.microsoft.com/semantic-kernel/semantic-kernel-planners-sequential-planner/">
|
||||
* Sequential Planner</a>
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example12_SequentialPlanner {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Example12_SequentialPlanner.class);
|
||||
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
poetrySamplesAsync();
|
||||
emailSamplesAsync();
|
||||
bookSamplesAsync();
|
||||
//MemorySampleAsync();
|
||||
}
|
||||
|
||||
private static void poetrySamplesAsync() throws ConfigurationException {
|
||||
System.out.println("======== Sequential Planner - Create and Execute Poetry Plan ========");
|
||||
var kernel = initializeKernel();
|
||||
|
||||
kernel.importSkill(new TextSkill(), "TextSkill");
|
||||
|
||||
var planner = new SequentialPlanner(kernel, null, null);
|
||||
|
||||
var plan = planner.createPlanAsync("Write a poem about John Doe, then translate it into Italian, then convert it to uppercase.").block();
|
||||
|
||||
// Original plan:
|
||||
// Goal: Write a poem about John Doe, then translate it into Italian.
|
||||
|
||||
// Steps:
|
||||
// - WriterSkill.ShortPoem INPUT='John Doe is a friendly guy who likes to help others and enjoys reading books.' =>
|
||||
// - WriterSkill.Translate language='Italian' INPUT='' =>
|
||||
|
||||
SKContext result = plan.invokeAsync().block();
|
||||
|
||||
System.out.println("Result:");
|
||||
System.out.println(result.getResult());
|
||||
}
|
||||
|
||||
public static class EmailSkill {
|
||||
@DefineSKFunction(name = "SendEmail", description = "Given an e-mail and message body, send an email")
|
||||
public void sendEmail(
|
||||
@SKFunctionInputAttribute(description = "The body of the email message to send.")
|
||||
String input,
|
||||
@SKFunctionParameters(description = "The email address to send email to.", name = "email_address")
|
||||
String emailAddress
|
||||
) {
|
||||
LOGGER.info("Emailing to " + emailAddress + "\n" + input);
|
||||
}
|
||||
|
||||
@DefineSKFunction(name = "GetEmailAddressAsync", description = "Lookup an email address for a person given a name")
|
||||
public String getEmailAddressAsync(
|
||||
@SKFunctionInputAttribute(description = "The name of the person to email.")
|
||||
String input) {
|
||||
return "[email protected]";
|
||||
}
|
||||
}
|
||||
|
||||
private static void emailSamplesAsync() throws ConfigurationException {
|
||||
System.out.println("======== Sequential Planner - Create and Execute Email Plan ========");
|
||||
var kernel = initializeKernel();
|
||||
|
||||
kernel.importSkill(new EmailSkill(), "email");
|
||||
|
||||
|
||||
SequentialPlanner planner = initPlanner(kernel, 1024);
|
||||
|
||||
var plan = planner.createPlanAsync("Summarize an input, translate to french, and e-mail to John Doe").block();
|
||||
|
||||
// Original plan:
|
||||
// Goal: Summarize an input, translate to french, and e-mail to John Doe
|
||||
|
||||
// Steps:
|
||||
// - SummarizeSkill.Summarize INPUT='' =>
|
||||
// - WriterSkill.Translate language='French' INPUT='' => TRANSLATED_SUMMARY
|
||||
// - email.GetEmailAddress INPUT='John Doe' => EMAIL_ADDRESS
|
||||
// - email.SendEmail INPUT='$TRANSLATED_SUMMARY' email_address='$EMAIL_ADDRESS' =>
|
||||
|
||||
System.out.println("Original plan:");
|
||||
System.out.println(plan.toManualString(false));
|
||||
|
||||
var input =
|
||||
"Once upon a time, in a faraway kingdom, there lived a kind and just king named Arjun. " +
|
||||
"He ruled over his kingdom with fairness and compassion, earning him the love and admiration of his people. " +
|
||||
"However, the kingdom was plagued by a terrible dragon that lived in the nearby mountains and terrorized the nearby villages, " +
|
||||
"burning their crops and homes. The king had tried everything to defeat the dragon, but to no avail. " +
|
||||
"One day, a young woman named Mira approached the king and offered to help defeat the dragon. She was a skilled archer " +
|
||||
"and claimed that she had a plan to defeat the dragon once and for all. The king was skeptical, but desperate for a solution, " +
|
||||
"so he agreed to let her try. Mira set out for the dragon's lair and, with the help of her trusty bow and arrow, " +
|
||||
"she was able to strike the dragon with a single shot through its heart, killing it instantly. The people rejoiced " +
|
||||
"and the kingdom was at peace once again. The king was so grateful to Mira that he asked her to marry him and she agreed. " +
|
||||
"They ruled the kingdom together, ruling with fairness and compassion, just as Arjun had done before. They lived " +
|
||||
"happily ever after, with the people of the kingdom remembering Mira as the brave young woman who saved them from the dragon.";
|
||||
|
||||
plan.invokeAsync(input).blockOptional();
|
||||
}
|
||||
|
||||
private static void bookSamplesAsync() throws ConfigurationException {
|
||||
System.out.println("======== Sequential Planner - Create and Execute Book Creation Plan ========");
|
||||
var kernel = initializeKernel();
|
||||
|
||||
SequentialPlanner planner = initPlanner(kernel, 1024);
|
||||
|
||||
var plan = planner.createPlanAsync("Create a book with 3 chapters about a group of kids in a club called 'The Thinking Caps.'").block();
|
||||
|
||||
// Original plan:
|
||||
// Goal: Create a book with 3 chapters about a group of kids in a club called 'The Thinking Caps.'
|
||||
|
||||
// Steps:
|
||||
// - WriterSkill.NovelOutline chapterCount='3' INPUT='A group of kids in a club called 'The Thinking Caps' that solve mysteries and puzzles using their creativity and logic.' endMarker='<!--===ENDPART===-->' => OUTLINE
|
||||
// - MiscSkill.ElementAtIndex count='3' INPUT='$OUTLINE' index='0' => CHAPTER_1_SYNOPSIS
|
||||
// - WriterSkill.NovelChapter chapterIndex='1' previousChapter='' INPUT='$CHAPTER_1_SYNOPSIS' theme='Children's mystery' => RESULT__CHAPTER_1
|
||||
// - MiscSkill.ElementAtIndex count='3' INPUT='$OUTLINE' index='1' => CHAPTER_2_SYNOPSIS
|
||||
// - WriterSkill.NovelChapter chapterIndex='2' previousChapter='$CHAPTER_1_SYNOPSIS' INPUT='$CHAPTER_2_SYNOPSIS' theme='Children's mystery' => RESULT__CHAPTER_2
|
||||
// - MiscSkill.ElementAtIndex count='3' INPUT='$OUTLINE' index='2' => CHAPTER_3_SYNOPSIS
|
||||
// - WriterSkill.NovelChapter chapterIndex='3' previousChapter='$CHAPTER_2_SYNOPSIS' INPUT='$CHAPTER_3_SYNOPSIS' theme='Children's mystery' => RESULT__CHAPTER_3
|
||||
System.out.println(plan.invokeAsync().block().getResult());
|
||||
}
|
||||
|
||||
/*
|
||||
TODO
|
||||
private static void memorySampleAsync() throws IOException {
|
||||
System.out.println("======== Sequential Planner - Create and Execute Plan using Memory ========");
|
||||
var kernel = initializeKernel();
|
||||
|
||||
SequentialPlanner planner = initPlanner(kernel, 1024);
|
||||
|
||||
kernel.importSkillsFromDirectory("samples/skills",
|
||||
"CalendarSkill",
|
||||
"ChatSkill",
|
||||
"ChildrensBookSkill",
|
||||
"ClassificationSkill",
|
||||
"CodingSkill",
|
||||
"FunSkill",
|
||||
"IntentDetectionSkill",
|
||||
"MiscSkill",
|
||||
"QASkill");
|
||||
|
||||
kernel.importSkill(new EmailSkill(), "email");
|
||||
kernel.importSkill(new StaticTextSkill(), "statictext");
|
||||
kernel.importSkill(new TextSkill(), "text");
|
||||
kernel.importSkill(new Microsoft.SemanticKernel.CoreSkills.TextSkill(), "coretext");
|
||||
|
||||
var goal = "Create a book with 3 chapters about a group of kids in a club called 'The Thinking Caps.'";
|
||||
|
||||
var planner = new SequentialPlanner(kernel, new SequentialPlannerConfig {
|
||||
RelevancyThreshold =0.78
|
||||
});
|
||||
|
||||
var plan = await planner.CreatePlanAsync(goal);
|
||||
|
||||
System.out.println("Original plan:");
|
||||
System.out.println(plan.ToPlanString());
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
private static Kernel initializeKernel() throws ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
var kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(SKBuilders.textCompletion()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId("gpt-35-turbo-instruct")
|
||||
.build())
|
||||
.withMemory(SKBuilders
|
||||
.semanticTextMemory()
|
||||
.withEmbeddingGenerator(
|
||||
SKBuilders.textEmbeddingGeneration()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId("text-embedding-ada-002")
|
||||
.build()
|
||||
)
|
||||
.withStorage(new VolatileMemoryStore())
|
||||
.build())
|
||||
.build();
|
||||
|
||||
|
||||
// Load additional skills to enable planner to do non-trivial asks.
|
||||
kernel.importSkillFromDirectory("SummarizeSkill", SampleSkillsUtil.detectSkillDirLocation(), "SummarizeSkill");
|
||||
kernel.importSkillFromDirectory("WriterSkill", SampleSkillsUtil.detectSkillDirLocation(), "WriterSkill");
|
||||
kernel.importSkillFromDirectory("MiscSkill", SampleSkillsUtil.detectSkillDirLocation(), "MiscSkill");
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
||||
private static SequentialPlanner initPlanner(Kernel kernel, int maxTokens) {
|
||||
return new SequentialPlanner(kernel, new SequentialPlannerRequestSettings(
|
||||
null,
|
||||
100,
|
||||
Set.of(),
|
||||
Set.of(),
|
||||
Set.of(),
|
||||
maxTokens,
|
||||
false
|
||||
), null);
|
||||
}
|
||||
}
|
||||
-196
@@ -1,196 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.coreskills.ConversationSummarySkill;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.ReadOnlyFunctionCollection;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Demonstrate the {@code com.microsoft.semantickernel.coreskills.ConversationSummarySkill}
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example13_ConversationSummarySkill {
|
||||
private static final String ChatTranscript =
|
||||
"""
|
||||
John: Hello, how are you?
|
||||
Jane: I'm fine, thanks. How are you?
|
||||
John: I'm doing well, writing some example code.
|
||||
Jane: That's great! I'm writing some example code too.
|
||||
John: What are you writing?
|
||||
Jane: I'm writing a chatbot.
|
||||
John: That's cool. I'm writing a chatbot too.
|
||||
Jane: What language are you writing it in?
|
||||
John: I'm writing it in C#.
|
||||
Jane: I'm writing it in Python.
|
||||
John: That's cool. I need to learn Python.
|
||||
Jane: I need to learn C#.
|
||||
John: Can I try out your chatbot?
|
||||
Jane: Sure, here's the link.
|
||||
John: Thanks!
|
||||
Jane: You're welcome.
|
||||
Jane: Look at this poem my chatbot wrote:
|
||||
Jane: Roses are red
|
||||
Jane: Violets are blue
|
||||
Jane: I'm writing a chatbot
|
||||
Jane: What about you?
|
||||
John: That's cool. Let me see if mine will write a poem, too.
|
||||
John: Here's a poem my chatbot wrote:
|
||||
John: The singularity of the universe is a mystery.
|
||||
John: The universe is a mystery.
|
||||
John: The universe is a mystery.
|
||||
John: The universe is a mystery.
|
||||
John: Looks like I need to improve mine, oh well.
|
||||
Jane: You might want to try using a different model.
|
||||
Jane: I'm using the GPT-3 model.
|
||||
John: I'm using the GPT-2 model. That makes sense.
|
||||
John: Here is a new poem after updating the model.
|
||||
John: The universe is a mystery.
|
||||
John: The universe is a mystery.
|
||||
John: The universe is a mystery.
|
||||
John: Yikes, it's really stuck isn't it. Would you help me debug my code?
|
||||
Jane: Sure, what's the problem?
|
||||
John: I'm not sure. I think it's a bug in the code.
|
||||
Jane: I'll take a look.
|
||||
Jane: I think I found the problem.
|
||||
Jane: It looks like you're not passing the right parameters to the model.
|
||||
John: Thanks for the help!
|
||||
Jane: I'm now writing a bot to summarize conversations. I want to make sure it works when the conversation is long.
|
||||
John: So you need to keep talking with me to generate a long conversation?
|
||||
Jane: Yes, that's right.
|
||||
John: Ok, I'll keep talking. What should we talk about?
|
||||
Jane: I don't know, what do you want to talk about?
|
||||
John: I don't know, it's nice how CoPilot is doing most of the talking for us. But it definitely gets stuck sometimes.
|
||||
Jane: I agree, it's nice that CoPilot is doing most of the talking for us.
|
||||
Jane: But it definitely gets stuck sometimes.
|
||||
John: Do you know how long it needs to be?
|
||||
Jane: I think the max length is 1024 tokens. Which is approximately 1024*4= 4096 characters.
|
||||
John: That's a lot of characters.
|
||||
Jane: Yes, it is.
|
||||
John: I'm not sure how much longer I can keep talking.
|
||||
Jane: I think we're almost there. Let me check.
|
||||
Jane: I have some bad news, we're only half way there.
|
||||
John: Oh no, I'm not sure I can keep going. I'm getting tired.
|
||||
Jane: I'm getting tired too.
|
||||
John: Maybe there is a large piece of text we can use to generate a long conversation.
|
||||
Jane: That's a good idea. Let me see if I can find one. Maybe Lorem Ipsum?
|
||||
John: Yeah, that's a good idea.
|
||||
Jane: I found a Lorem Ipsum generator.
|
||||
Jane: Here's a 4096 character Lorem Ipsum text:
|
||||
Jane: Lorem ipsum dolor sit amet, con
|
||||
Jane: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nunc sit amet aliquam
|
||||
Jane: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nunc sit amet aliquam
|
||||
Jane: Darn, it's just repeating stuf now.
|
||||
John: I think we're done.
|
||||
Jane: We're not though! We need like 1500 more characters.
|
||||
John: Oh Cananda, our home and native land.
|
||||
Jane: True patriot love in all thy sons command.
|
||||
John: With glowing hearts we see thee rise.
|
||||
Jane: The True North strong and free.
|
||||
John: From far and wide, O Canada, we stand on guard for thee.
|
||||
Jane: God keep our land glorious and free.
|
||||
John: O Canada, we stand on guard for thee.
|
||||
Jane: O Canada, we stand on guard for thee.
|
||||
Jane: That was fun, thank you. Let me check now.
|
||||
Jane: I think we need about 600 more characters.
|
||||
John: Oh say can you see?
|
||||
Jane: By the dawn's early light.
|
||||
John: What so proudly we hailed.
|
||||
Jane: At the twilight's last gleaming.
|
||||
John: Whose broad stripes and bright stars.
|
||||
Jane: Through the perilous fight.
|
||||
John: O'er the ramparts we watched.
|
||||
Jane: Were so gallantly streaming.
|
||||
John: And the rockets' red glare.
|
||||
Jane: The bombs bursting in air.
|
||||
John: Gave proof through the night.
|
||||
Jane: That our flag was still there.
|
||||
John: Oh say does that star-spangled banner yet wave.
|
||||
Jane: O'er the land of the free.
|
||||
John: And the home of the brave.
|
||||
Jane: Are you a Seattle Kraken Fan?
|
||||
John: Yes, I am. I love going to the games.
|
||||
Jane: I'm a Seattle Kraken Fan too. Who is your favorite player?
|
||||
John: I like watching all the players, but I think my favorite is Matty Beniers.
|
||||
Jane: Yeah, he's a great player. I like watching him too. I also like watching Jaden Schwartz.
|
||||
John: Adam Larsson is another good one. The big cat!
|
||||
Jane: WE MADE IT! It's long enough. Thank you!
|
||||
John: Can you automate generating long text next time?
|
||||
Jane: I will.
|
||||
John: You're welcome. I'm glad we could help. Goodbye!
|
||||
Jane: Goodbye!
|
||||
""".stripIndent();
|
||||
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
|
||||
conversationSummarySkillAsync(client);
|
||||
getConversationActionItemsAsync(client);
|
||||
getConversationTopicsAsync(client);
|
||||
}
|
||||
|
||||
private static void conversationSummarySkillAsync(OpenAIAsyncClient client) {
|
||||
System.out.println("======== SampleSkills - Conversation Summary Skill - Summarize ========");
|
||||
Kernel kernel = initializeKernel(client);
|
||||
|
||||
ReadOnlyFunctionCollection conversationSummarySkill =
|
||||
kernel.importSkill(new ConversationSummarySkill(kernel), null);
|
||||
|
||||
Mono<SKContext> summary = conversationSummarySkill
|
||||
.getFunction("SummarizeConversation", SKFunction.class)
|
||||
.invokeAsync(ChatTranscript);
|
||||
|
||||
System.out.println("Generated Summary (This may take some time):");
|
||||
System.out.println(summary.block().getResult());
|
||||
}
|
||||
|
||||
|
||||
private static void getConversationActionItemsAsync(OpenAIAsyncClient client) {
|
||||
System.out.println("======== SampleSkills - Conversation Summary Skill - Action Items ========");
|
||||
Kernel kernel = initializeKernel(client);
|
||||
|
||||
ReadOnlyFunctionCollection conversationSummarySkill =
|
||||
kernel.importSkill(new ConversationSummarySkill(kernel), null);
|
||||
|
||||
Mono<SKContext> summary = conversationSummarySkill
|
||||
.getFunction("GetConversationActionItems", SKFunction.class)
|
||||
.invokeAsync(ChatTranscript);
|
||||
|
||||
System.out.println("Generated Action Items (This may take some time):");
|
||||
System.out.println(summary.block().getResult());
|
||||
}
|
||||
|
||||
private static void getConversationTopicsAsync(OpenAIAsyncClient client) {
|
||||
Kernel kernel = initializeKernel(client);
|
||||
|
||||
ReadOnlyFunctionCollection conversationSummarySkill =
|
||||
kernel.importSkill(new ConversationSummarySkill(kernel), null);
|
||||
|
||||
Mono<SKContext> summary = conversationSummarySkill
|
||||
.getFunction("GetConversationTopics", SKFunction.class)
|
||||
.invokeAsync(ChatTranscript);
|
||||
|
||||
System.out.println("Generated Topics:");
|
||||
System.out.println(summary.block().getResult());
|
||||
}
|
||||
|
||||
private static Kernel initializeKernel(OpenAIAsyncClient client) {
|
||||
TextCompletion textCompletion = SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build();
|
||||
|
||||
return SKBuilders.kernel()
|
||||
.withAIService("text-davinci-003", textCompletion, true, TextCompletion.class).build();
|
||||
}
|
||||
}
|
||||
-213
@@ -1,213 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.core.credential.TokenCredential;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.util.AzureCredentialType;
|
||||
import com.microsoft.semantickernel.connectors.memory.azurecognitivesearch.AzureCognitiveSearchMemoryStore;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.memory.VolatileMemoryStore;
|
||||
import com.microsoft.semantickernel.settings.SettingsMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
||||
/**
|
||||
* Demonstrate two examples about SK Semantic Memory:
|
||||
*
|
||||
* 1. Memory using Azure Cognitive Search.
|
||||
* 2. Memory using a custom embedding generator and vector engine.
|
||||
*
|
||||
* Semantic Memory allows to store your data like traditional DBs,
|
||||
* adding the ability to query it using natural language.
|
||||
* <p>
|
||||
* You must <a href=
|
||||
* "https://learn.microsoft.com/en-us/azure/search/search-create-service-portal">
|
||||
* create an Azure Cognitive Search service in the portal</a> to run this example.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example14_SemanticMemory {
|
||||
|
||||
private static final String MEMORY_COLLECTION_NAME = "SKGitHub";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("==============================================================");
|
||||
System.out.println("======== Semantic Memory using Azure Cognitive Search ========");
|
||||
System.out.println("==============================================================");
|
||||
|
||||
var openAIAsyncClient = SamplesConfig.getClient();
|
||||
|
||||
AzureCognitiveSearchMemoryStore memoryStore = buildAzureCognitiveSearchMemoryStore();
|
||||
/* This example leverages Azure Cognitive Search to provide SK with Semantic Memory.
|
||||
*
|
||||
* Azure Cognitive Search automatically indexes your data semantically, so you don't
|
||||
* need to worry about embedding generation.
|
||||
*/
|
||||
var kernelWithACS = SKBuilders.kernel()
|
||||
.withMemoryStorage(memoryStore)
|
||||
.withDefaultAIService(SKBuilders.textEmbeddingGeneration()
|
||||
.withOpenAIClient(openAIAsyncClient)
|
||||
.withModelId("text-embedding-ada-002")
|
||||
.build())
|
||||
.build();
|
||||
|
||||
runExampleAsync(kernelWithACS).block();
|
||||
|
||||
System.out.println("====================================================");
|
||||
System.out.println("======== Semantic Memory (volatile, in RAM) ========");
|
||||
System.out.println("====================================================");
|
||||
|
||||
/* You can build your own semantic memory combining an Embedding Generator
|
||||
* with a Memory storage that supports search by similarity (ie semantic search).
|
||||
*
|
||||
* In this example we use a volatile memory, a local simulation of a vector DB.
|
||||
*
|
||||
* You can replace VolatileMemoryStore with Qdrant (see QdrantMemoryStore connector)
|
||||
* or implement your connectors for Pinecone, Vespa, Postgres + pgvector, SQLite VSS, etc.
|
||||
*/
|
||||
|
||||
var kernelWithCustomDb = SKBuilders.kernel()
|
||||
.withDefaultAIService(SKBuilders.textEmbeddingGeneration()
|
||||
.withOpenAIClient(openAIAsyncClient)
|
||||
.withModelId("text-embedding-ada-002")
|
||||
.build())
|
||||
.withMemoryStorage(new VolatileMemoryStore.Builder().build())
|
||||
.build();
|
||||
|
||||
runExampleAsync(kernelWithCustomDb).block();
|
||||
}
|
||||
|
||||
private static AzureCognitiveSearchMemoryStore buildAzureCognitiveSearchMemoryStore()
|
||||
throws ConfigurationException {
|
||||
Map<String, String> settings = SettingsMap.getDefault();
|
||||
|
||||
AzureCognitiveSearchMemoryStore memoryStore;
|
||||
|
||||
if (settings.get("cognativesearch.token") == null) {
|
||||
// Attempt to obtain token via
|
||||
TokenCredential token = AzureCredentialType.getCredential();
|
||||
if (token == null) {
|
||||
throw new IllegalStateException(
|
||||
"Unable to obtain token credentials. Please provide a key for Azure Cognitive Search, or log in to az.");
|
||||
}
|
||||
memoryStore = new AzureCognitiveSearchMemoryStore(
|
||||
settings.get("cognativesearch.endpoint"),
|
||||
token
|
||||
);
|
||||
} else {
|
||||
memoryStore = new AzureCognitiveSearchMemoryStore(
|
||||
settings.get("cognativesearch.endpoint"),
|
||||
settings.get("cognativesearch.token")
|
||||
);
|
||||
}
|
||||
return memoryStore;
|
||||
}
|
||||
|
||||
public static Mono<Void> runExampleAsync(Kernel kernel) {
|
||||
return storeMemoryAsync(kernel)
|
||||
.then(searchMemoryAsync(kernel, "How do I get started?"))
|
||||
|
||||
/*
|
||||
Output:
|
||||
|
||||
Query: How do I get started?
|
||||
|
||||
Result 1:
|
||||
URL: : https://github.com/microsoft/semantic-kernel/blob/main/README.md
|
||||
Title : README: Installation, getting started, and how to contribute
|
||||
|
||||
Result 2:
|
||||
URL: : https://github.com/microsoft/semantic-kernel/blob/main/samples/dotnet-jupyter-notebooks/00-getting-started.ipynb
|
||||
Title : Jupyter notebook describing how to get started with the Semantic Kernel
|
||||
|
||||
*/
|
||||
|
||||
.then(searchMemoryAsync(kernel, "Can I build a chat with SK?"));
|
||||
|
||||
/*
|
||||
Output:
|
||||
|
||||
Query: Can I build a chat with SK?
|
||||
|
||||
Result 1:
|
||||
URL: : https://github.com/microsoft/semantic-kernel/tree/main/samples/skills/ChatSkill/ChatGPT
|
||||
Title : Sample demonstrating how to create a chat skill interfacing with ChatGPT
|
||||
|
||||
Result 2:
|
||||
URL: : https://github.com/microsoft/semantic-kernel/blob/main/samples/apps/chat-summary-webapp-react/README.md
|
||||
Title : README: README associated with a sample chat summary react-based webapp
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
private static Mono<Void> searchMemoryAsync(Kernel kernel, String query) {
|
||||
return kernel.getMemory().searchAsync(MEMORY_COLLECTION_NAME, query, 2, 0.5f, false)
|
||||
.mapNotNull(memories -> {
|
||||
System.out.println("\nQuery: " + query + "\n");
|
||||
for (int n = 0; n < memories.size(); n++) {
|
||||
var memory = memories.get(n);
|
||||
System.out.println("Result " + (n + 1) + ":");
|
||||
System.out.println(" URL: : " + memory.getMetadata().getId());
|
||||
System.out.println(" Title : " + memory.getMetadata().getDescription());
|
||||
System.out.println();
|
||||
}
|
||||
System.out.println("----------------------");
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private static Mono<Void> storeMemoryAsync(Kernel kernel) {
|
||||
/* Store some data in the semantic memory.
|
||||
*
|
||||
* When using Azure Cognitive Search the data is automatically indexed on write.
|
||||
*
|
||||
* When using the combination of VolatileStore and Embedding generation, SK takes
|
||||
* care of creating and storing the index
|
||||
*/
|
||||
|
||||
return Flux.fromIterable(sampleData().entrySet())
|
||||
.doFirst(() -> System.out.println(
|
||||
"\nAdding some GitHub file URLs and their descriptions to the semantic memory."))
|
||||
.map(entry -> {
|
||||
System.out.println("Save '" + entry.getKey() + "' to memory.");
|
||||
return kernel.getMemory().saveReferenceAsync(
|
||||
MEMORY_COLLECTION_NAME,
|
||||
entry.getValue(),
|
||||
entry.getKey(),
|
||||
"GitHub",
|
||||
entry.getValue(),
|
||||
null);
|
||||
}
|
||||
)
|
||||
.mapNotNull(Mono::block)
|
||||
.doFinally(signalType -> System.out.println("\n----------------------"))
|
||||
.then();
|
||||
}
|
||||
|
||||
private static Map<String, String> sampleData() {
|
||||
return Arrays.stream(new String[][]{
|
||||
{"https://github.com/microsoft/semantic-kernel/blob/main/README.md",
|
||||
"README: Installation, getting started, and how to contribute"},
|
||||
{"https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/dotnet/02-running-prompts-from-file.ipynb",
|
||||
"Jupyter notebook describing how to pass prompts from a file to a semantic skill or function"},
|
||||
{"https://github.com/microsoft/semantic-kernel/blob/main/samples/notebooks/dotnet/00-getting-started.ipynb",
|
||||
"Jupyter notebook describing how to get started with the Semantic Kernel"},
|
||||
{"https://github.com/microsoft/semantic-kernel/tree/main/samples/skills/ChatSkill/ChatGPT",
|
||||
"Sample demonstrating how to create a chat skill interfacing with ChatGPT"},
|
||||
{"https://github.com/microsoft/semantic-kernel/blob/main/dotnet/src/SemanticKernel/Memory/VolatileMemoryStore.cs",
|
||||
"C# class that defines a volatile embedding store"},
|
||||
{"https://github.com/microsoft/semantic-kernel/blob/main/samples/dotnet/KernelHttpServer/README.md",
|
||||
"README: How to set up a Semantic Kernel Service API using Azure Function Runtime v4"},
|
||||
{"https://github.com/microsoft/semantic-kernel/blob/main/samples/apps/chat-summary-webapp-react/README.md",
|
||||
"README: README associated with a sample chat summary react-based webapp"},
|
||||
}).collect(Collectors.toMap(element -> element[0], element -> element[1]));
|
||||
}
|
||||
}
|
||||
-229
@@ -1,229 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.ai.embeddings.TextEmbeddingGeneration;
|
||||
import com.microsoft.semantickernel.coreskills.TextMemorySkill;
|
||||
import com.microsoft.semantickernel.memory.MemoryStore;
|
||||
import com.microsoft.semantickernel.memory.VolatileMemoryStore;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Demonstrates saving and retrieving memories.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example15_MemorySkill {
|
||||
private static final String MEMORY_COLLECTION_NAME = "aboutMe";
|
||||
|
||||
public static void main(String[] args) {
|
||||
runAsync().block();
|
||||
}
|
||||
|
||||
public static Mono<Void> runAsync() {
|
||||
// ========= Create a kernel =========
|
||||
OpenAIAsyncClient client = null;
|
||||
try {
|
||||
client = SamplesConfig.getClient();
|
||||
} catch (Exception e) {
|
||||
return Mono.error(e);
|
||||
}
|
||||
|
||||
TextCompletion textCompletionService =
|
||||
SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build();
|
||||
|
||||
TextEmbeddingGeneration textEmbeddingGenerationService =
|
||||
SKBuilders.textEmbeddingGeneration()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId("text-embedding-ada-002")
|
||||
.build();
|
||||
|
||||
MemoryStore memoryStore = new VolatileMemoryStore.Builder().build();
|
||||
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(textCompletionService)
|
||||
.withDefaultAIService(textEmbeddingGenerationService)
|
||||
.withMemoryStorage(memoryStore)
|
||||
.build();
|
||||
|
||||
// ========= Store memories using the kernel =========
|
||||
|
||||
kernel.getMemory().saveInformationAsync(MEMORY_COLLECTION_NAME, "My name is Andrea", "info1", null, null).block();
|
||||
kernel.getMemory().saveInformationAsync(MEMORY_COLLECTION_NAME, "I work as a tourist operator", "info2", null, null).block();
|
||||
kernel.getMemory().saveInformationAsync(MEMORY_COLLECTION_NAME, "I've been living in Seattle since 2005", "info3", null, null).block();
|
||||
kernel.getMemory().saveInformationAsync(MEMORY_COLLECTION_NAME, "I visited France and Italy five times since 2015", "info4", null, null).block();
|
||||
|
||||
// ========= Store memories using semantic function =========
|
||||
|
||||
// Add Memory as a skill for other functions
|
||||
TextMemorySkill memorySkill = new TextMemorySkill();
|
||||
kernel.importSkill(memorySkill, "memory");
|
||||
|
||||
// Build a semantic function that saves info to memory
|
||||
PromptTemplateConfig.CompletionConfig completionConfig = SKBuilders.completionConfig()
|
||||
.temperature(0.2)
|
||||
.topP(0.5)
|
||||
.presencePenalty(0)
|
||||
.frequencyPenalty(0)
|
||||
.maxTokens(2000)
|
||||
.build();
|
||||
|
||||
CompletionSKFunction saveFunctionDefinition = SKBuilders.completionFunctions()
|
||||
.withKernel(kernel)
|
||||
.withPromptTemplate("{{memory.save $info}}")
|
||||
.withFunctionName("save")
|
||||
.withDescription("save information to memory")
|
||||
.withCompletionConfig(completionConfig)
|
||||
.build();
|
||||
|
||||
CompletionSKFunction memorySaver =
|
||||
kernel.registerSemanticFunction(saveFunctionDefinition);
|
||||
|
||||
SKContext context = SKBuilders.context()
|
||||
.withMemory(kernel.getMemory())
|
||||
.withSkills(kernel.getSkills())
|
||||
.build();
|
||||
|
||||
context.setVariable(TextMemorySkill.COLLECTION_PARAM, MEMORY_COLLECTION_NAME)
|
||||
.setVariable(TextMemorySkill.KEY_PARAM, "info5")
|
||||
.setVariable(TextMemorySkill.INFO_PARAM, "My family is from New York");
|
||||
|
||||
memorySaver.invokeAsync(context).block();
|
||||
|
||||
// ========= Test memory remember =========
|
||||
System.out.println("========= Example: Recalling a Memory =========");
|
||||
|
||||
// create a new context to avoid using the variables from the previous example
|
||||
context = SKBuilders.context()
|
||||
.withMemory(kernel.getMemory())
|
||||
.withSkills(kernel.getSkills())
|
||||
.build();
|
||||
|
||||
String answer = memorySkill.retrieveAsync(MEMORY_COLLECTION_NAME, "info1", context).block();
|
||||
System.out.printf("Memory associated with 'info1': %s%n", answer);
|
||||
/*
|
||||
Output:
|
||||
"Memory associated with 'info1': My name is Andrea
|
||||
*/
|
||||
|
||||
// ========= Test memory recall =========
|
||||
System.out.println("========= Example: Recalling an Idea =========");
|
||||
|
||||
List<String> answers = memorySkill.recallAsync(
|
||||
"Where did I grow up?",
|
||||
MEMORY_COLLECTION_NAME,
|
||||
0,
|
||||
2,
|
||||
context).block();
|
||||
|
||||
System.out.println("Ask: Where did I grow up?");
|
||||
System.out.printf("Answer:%n\t%s%n", answers.stream().collect(Collectors.joining("\",\"", "[\"", "\"]")));
|
||||
|
||||
answers = memorySkill.recallAsync(
|
||||
"Where do I live?",
|
||||
MEMORY_COLLECTION_NAME,
|
||||
0,
|
||||
2,
|
||||
context).block();
|
||||
|
||||
System.out.println("Ask: Where do I live?");
|
||||
System.out.printf("Answer:%n\t%s%n", answers.stream().collect(Collectors.joining("\",\"", "[\"", "\"]")));
|
||||
|
||||
/*
|
||||
Output:
|
||||
|
||||
Ask: where did I grow up?
|
||||
Answer:
|
||||
["My family is from New York","I've been living in Seattle since 2005"]
|
||||
|
||||
Ask: where do I live?
|
||||
Answer:
|
||||
["I've been living in Seattle since 2005","My family is from New York"]
|
||||
*/
|
||||
|
||||
// ========= Use memory in a semantic function =========
|
||||
System.out.println("========= Example: Using Recall in a Semantic Function =========");
|
||||
|
||||
// Build a semantic function that uses memory to find facts
|
||||
String prompt =
|
||||
"Consider only the facts below when answering questions.\n" +
|
||||
"About me: {{memory.recall 'where did I grow up?'}}\n" +
|
||||
"About me: {{memory.recall 'where do I live?'}}\n" +
|
||||
"Question: {{$input}}\n" +
|
||||
"Answer: ";
|
||||
|
||||
CompletionSKFunction recallFunctionDefinition = SKBuilders.completionFunctions()
|
||||
.withKernel(kernel)
|
||||
.withPromptTemplate(prompt)
|
||||
.withCompletionConfig(completionConfig)
|
||||
.build();
|
||||
|
||||
SKFunction<?> aboutMeOracle = kernel.registerSemanticFunction(recallFunctionDefinition);
|
||||
|
||||
context.setVariable(TextMemorySkill.COLLECTION_PARAM, MEMORY_COLLECTION_NAME)
|
||||
.setVariable(TextMemorySkill.RELEVANCE_PARAM, "0.75");
|
||||
|
||||
SKContext result = aboutMeOracle.invokeAsync("Do I live in the same town where I grew up?", context, null).block();
|
||||
|
||||
System.out.println("Do I live in the same town where I grew up?\n");
|
||||
System.out.println(result.getResult());
|
||||
|
||||
/*
|
||||
Output:
|
||||
|
||||
Do I live in the same town where I grew up?
|
||||
|
||||
No, I do not live in the same town where I grew up since my family is from New York and I have been living in Seattle since 2005.
|
||||
*/
|
||||
|
||||
// ========= Remove a memory =========
|
||||
System.out.println("========= Example: Forgetting a Memory =========");
|
||||
|
||||
context.setVariable("fact1", "What is my name?")
|
||||
.setVariable("fact2", "What do I do for a living?")
|
||||
.setVariable(TextMemorySkill.RELEVANCE_PARAM, "0.75");
|
||||
|
||||
result = aboutMeOracle.invokeAsync("Tell me a bit about myself", context, null).block();
|
||||
|
||||
System.out.println("Tell me a bit about myself\n");
|
||||
System.out.println(result.getResult());
|
||||
|
||||
/*
|
||||
Approximate Output:
|
||||
Tell me a bit about myself
|
||||
|
||||
My name is Andrea and my family is from New York. I work as a tourist operator.
|
||||
*/
|
||||
|
||||
memorySkill.removeAsync(MEMORY_COLLECTION_NAME, "info1", context).block();
|
||||
|
||||
result = aboutMeOracle.invokeAsync("Tell me a bit about myself", context, null).block();
|
||||
|
||||
System.out.println("Tell me a bit about myself\n");
|
||||
System.out.println(result.getResult());
|
||||
|
||||
/*
|
||||
Approximate Output:
|
||||
Tell me a bit about myself
|
||||
|
||||
I'm from a family originally from New York and I work as a tourist operator. I've been living in Seattle since 2005.
|
||||
*/
|
||||
|
||||
return Mono.empty();
|
||||
}
|
||||
}
|
||||
-67
@@ -1,67 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletion;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.connectors.ai.openai.chatcompletion.OpenAIChatHistory;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
|
||||
/**
|
||||
* Demonstrates the use of Semantic Kernel with OpenAI ChatGPT API
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example17_ChatGPT {
|
||||
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withAIService(
|
||||
"gpt-35-turbo",
|
||||
SKBuilders.chatCompletion()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId("gpt-35-turbo")
|
||||
.build(),
|
||||
true,
|
||||
ChatCompletion.class
|
||||
)
|
||||
.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("Hi, I'm looking for book suggestions");
|
||||
messageOutputAsync(chatHistory);
|
||||
|
||||
// First bot assistant message
|
||||
String reply = chatGPT.generateMessageAsync(chatHistory, null).block();
|
||||
chatHistory.addAssistantMessage(reply);
|
||||
messageOutputAsync(chatHistory);
|
||||
|
||||
// Second user message
|
||||
chatHistory.addUserMessage(
|
||||
"I love history and philosophy, I'd like to learn something new about Greece, any suggestion?");
|
||||
messageOutputAsync(chatHistory);
|
||||
|
||||
// Second bot assistant message
|
||||
reply = chatGPT.generateMessageAsync(chatHistory, null).block();
|
||||
chatHistory.addAssistantMessage(reply);
|
||||
messageOutputAsync(chatHistory);
|
||||
}
|
||||
|
||||
private static void messageOutputAsync(ChatHistory chatHistory) {
|
||||
ChatHistory.Message message = chatHistory.getMessages().get(chatHistory.getMessages().size() - 1);
|
||||
|
||||
System.out.println(message.getAuthorRoles() + ": " + message.getContent());
|
||||
System.out.println("------------------------");
|
||||
}
|
||||
}
|
||||
-286
@@ -1,286 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.microsoft.semantickernel.ai.embeddings.Embedding;
|
||||
import com.microsoft.semantickernel.memory.MemoryRecord;
|
||||
import com.microsoft.semantickernel.memory.MemoryStore;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.stream.Collectors;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
/**
|
||||
* Demonstrates a custom implementation of {@code MemoryStore} that is read only.
|
||||
* In this sample, the data is stored in a JSON String and deserialized into an
|
||||
* {@code MemoryRecord[]}. For this specific sample, the implementation
|
||||
* of {@code MemoryStore} has a single collection, and thus does not need to be named.
|
||||
* It also assumes that the JSON formatted data can be deserialized into {@code MemoryRecord} objects.
|
||||
* @see MemoryRecord
|
||||
* @see MemoryStore
|
||||
*/
|
||||
public class Example25_ReadOnlyMemoryStore
|
||||
{
|
||||
public static void main(String[] args) {
|
||||
RunAsync().block();
|
||||
}
|
||||
|
||||
public static Mono<Void> RunAsync()
|
||||
{
|
||||
var store = new ReadOnlyMemoryStore(JSON_VECTOR_ENTRIES);
|
||||
|
||||
var embedding = new Embedding(Arrays.asList(22f, 4f, 6f));
|
||||
|
||||
System.out.println("Reading data from custom read-only memory store");
|
||||
Mono<?> mono = store.getAsync("collection", "key3", true)
|
||||
.mapNotNull(memoryRecord -> {
|
||||
String memoryRecordId = memoryRecord.getMetadata().getId();
|
||||
Embedding memoryRecordEmbedding = memoryRecord.getEmbedding();
|
||||
System.out.printf("ID = %s, Embedding = %s%n", memoryRecordId, embeddingVectorToString(memoryRecordEmbedding));
|
||||
return memoryRecord;
|
||||
});
|
||||
|
||||
mono = mono.then(
|
||||
store.getNearestMatchAsync("collection", embedding, 0f, true)
|
||||
.mapNotNull(result -> {
|
||||
Float similarity = result.getT2().floatValue();
|
||||
MemoryRecord memoryRecord = result.getT1();
|
||||
Embedding memoryRecordEmbedding = memoryRecord.getEmbedding();
|
||||
System.out.printf("Embedding = %s, Similarity = %f%n", embeddingVectorToString(memoryRecordEmbedding), similarity);
|
||||
return result;
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return mono.then();
|
||||
|
||||
}
|
||||
|
||||
private static String embeddingVectorToString(Embedding embedding) {
|
||||
StringJoiner stringJoiner = new StringJoiner(", ", "[", "]");
|
||||
embedding.getVector().stream().map(Number::toString).forEach(stringJoiner::add);
|
||||
return stringJoiner.toString();
|
||||
}
|
||||
|
||||
private static class ReadOnlyMemoryStore implements MemoryStore
|
||||
{
|
||||
private final MemoryRecord[] _memoryRecords;
|
||||
private final int _vectorSize = 3;
|
||||
|
||||
public ReadOnlyMemoryStore(String valueString)
|
||||
{
|
||||
try {
|
||||
_memoryRecords = new ObjectMapper().readValue(valueString, MemoryRecord[].class);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new RuntimeException("Unable to deserialize memory records");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> createCollectionAsync(String collectionName)
|
||||
{
|
||||
return Mono.error(() -> new UnsupportedOperationException("This is a read-only memory store"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteCollectionAsync(String collectionName)
|
||||
{
|
||||
return Mono.error(() -> new UnsupportedOperationException("This is a read-only memory store"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> doesCollectionExistAsync(String collectionName)
|
||||
{
|
||||
return Mono.error(() -> new UnsupportedOperationException("This is a read-only memory store"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<MemoryRecord> getAsync(String collectionName, String key, boolean withEmbedding)
|
||||
{
|
||||
// Note: with this simple implementation, the MemoryRecord will always contain the embedding.
|
||||
return Mono.justOrEmpty(
|
||||
Arrays.stream(this._memoryRecords)
|
||||
.filter(it -> it.getKey().equals(key))
|
||||
.findFirst()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Collection<MemoryRecord>> getBatchAsync(String collectionName, Collection<String> keys, boolean withEmbeddings)
|
||||
{
|
||||
// Note: with this simple implementation, the MemoryRecord will always contain the embedding.
|
||||
return Mono.just(
|
||||
Arrays.stream(this._memoryRecords)
|
||||
.filter(it -> keys.contains(it.getKey()))
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<List<String>> getCollectionsAsync()
|
||||
{
|
||||
return Mono.error(() -> new UnsupportedOperationException("This is a read-only memory store"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Tuple2<MemoryRecord, Float>> getNearestMatchAsync(String collectionName, Embedding embedding, float minRelevanceScore,
|
||||
boolean withEmbedding)
|
||||
{
|
||||
// Note: with this simple implementation, the MemoryRecord will always contain the embedding.
|
||||
return Mono.justOrEmpty(
|
||||
Arrays.stream(this._memoryRecords)
|
||||
.map(it -> {
|
||||
Embedding memoryRecordEmbedding =
|
||||
it.getEmbedding();
|
||||
float cosineSimilarity = -1f;
|
||||
try {
|
||||
cosineSimilarity = embedding.cosineSimilarity(memoryRecordEmbedding);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Vectors cannot have zero norm
|
||||
}
|
||||
return Tuples.of(it, cosineSimilarity);
|
||||
})
|
||||
.filter(it -> it.getT2() >= minRelevanceScore)
|
||||
.max(Comparator.comparing(Tuple2::getT2, Float::compare))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Collection<Tuple2<MemoryRecord, Float>>> getNearestMatchesAsync(String collectionName, Embedding embedding, int limit,
|
||||
float minRelevanceScore, boolean withEmbeddings)
|
||||
{
|
||||
// Note: with this simple implementation, the MemoryRecord will always contain the embedding.
|
||||
return Mono.justOrEmpty(
|
||||
Arrays.stream(this._memoryRecords)
|
||||
.map(it -> {
|
||||
Embedding memoryRecordEmbedding =
|
||||
it.getEmbedding();
|
||||
float cosineSimilarity = -1f;
|
||||
try {
|
||||
cosineSimilarity = embedding.cosineSimilarity(memoryRecordEmbedding);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Vectors cannot have zero norm
|
||||
}
|
||||
return Tuples.of(it, cosineSimilarity);
|
||||
})
|
||||
.filter(it -> it.getT2() >= (float)minRelevanceScore)
|
||||
// sort by similarity score, descending
|
||||
.sorted(Comparator.comparing(Tuple2::getT2, (a,b) -> Float.compare(b, a)))
|
||||
.limit(limit)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> removeAsync(String collectionName, String key)
|
||||
{
|
||||
return Mono.error(() -> new UnsupportedOperationException("This is a read-only memory store"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> removeBatchAsync(String collectionName, Collection<String> keys)
|
||||
{
|
||||
return Mono.error(() -> new UnsupportedOperationException("This is a read-only memory store"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<String> upsertAsync(String collectionName, MemoryRecord record)
|
||||
{
|
||||
return Mono.error(() -> new UnsupportedOperationException("This is a read-only memory store"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Collection<String>> upsertBatchAsync(String collectionName, Collection<MemoryRecord> records)
|
||||
{
|
||||
return Mono.error(() -> new UnsupportedOperationException("This is a read-only memory store"));
|
||||
}
|
||||
}
|
||||
|
||||
private static final String JSON_VECTOR_ENTRIES = """
|
||||
[
|
||||
{
|
||||
"embedding": {
|
||||
"vector": [0, 0, 0 ]
|
||||
},
|
||||
"metadata": {
|
||||
"is_reference": false,
|
||||
"external_source_name": "externalSourceName",
|
||||
"id": "Id1",
|
||||
"description": "description",
|
||||
"text": "text",
|
||||
"additional_metadata" : "value:"
|
||||
},
|
||||
"key": "key1",
|
||||
"timestamp": null
|
||||
},
|
||||
{
|
||||
"embedding": {
|
||||
"vector": [0, 0, 10 ]
|
||||
},
|
||||
"metadata": {
|
||||
"is_reference": false,
|
||||
"external_source_name": "externalSourceName",
|
||||
"id": "Id2",
|
||||
"description": "description",
|
||||
"text": "text",
|
||||
"additional_metadata" : "value:"
|
||||
},
|
||||
"key": "key2",
|
||||
"timestamp": null
|
||||
},
|
||||
{
|
||||
"embedding": {
|
||||
"vector": [1, 2, 3 ]
|
||||
},
|
||||
"metadata": {
|
||||
"is_reference": false,
|
||||
"external_source_name": "externalSourceName",
|
||||
"id": "Id3",
|
||||
"description": "description",
|
||||
"text": "text",
|
||||
"additional_metadata" : "value:"
|
||||
},
|
||||
"key": "key3",
|
||||
"timestamp": null
|
||||
},
|
||||
{
|
||||
"embedding": {
|
||||
"vector": [-1, -2, -3 ]
|
||||
},
|
||||
"metadata": {
|
||||
"is_reference": false,
|
||||
"external_source_name": "externalSourceName",
|
||||
"id": "Id4",
|
||||
"description": "description",
|
||||
"text": "text",
|
||||
"additional_metadata" : "value:"
|
||||
},
|
||||
"key": "key4",
|
||||
"timestamp": null
|
||||
},
|
||||
{
|
||||
"embedding": {
|
||||
"vector": [12, 8, 4 ]
|
||||
},
|
||||
"metadata": {
|
||||
"is_reference": false,
|
||||
"external_source_name": "externalSourceName",
|
||||
"id": "Id5",
|
||||
"description": "description",
|
||||
"text": "text",
|
||||
"additional_metadata" : "value:"
|
||||
},
|
||||
"key": "key5",
|
||||
"timestamp": null
|
||||
}
|
||||
]
|
||||
""".replaceAll(" |\\n", "");
|
||||
}
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.coreskills.TextSkill;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.planner.actionplanner.ActionPlanner;
|
||||
|
||||
/**
|
||||
* Demonstrates the <a href=
|
||||
* "https://devblogs.microsoft.com/semantic-kernel/semantic-kernel-planners-actionplanner/">
|
||||
* Action Planner</a>
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example28_ActionPlanner {
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
|
||||
System.out.println("======== Action Planner ========");
|
||||
|
||||
var kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
kernel.importSkillFromDirectory("SummarizeSkill", SampleSkillsUtil.detectSkillDirLocation(), "SummarizeSkill");
|
||||
|
||||
kernel.importSkillFromDirectory("WriterSkill", SampleSkillsUtil.detectSkillDirLocation(), "WriterSkill");
|
||||
|
||||
kernel.importSkill(new TextSkill(), "TextSkill");
|
||||
|
||||
// Create an instance of ActionPlanner.
|
||||
// The ActionPlanner takes one goal and returns a single function to execute.
|
||||
var planner = new ActionPlanner(kernel, null);
|
||||
|
||||
// We're going to ask the planner to find a function to achieve this goal.
|
||||
var goal = "Write a poem about Cleopatra.";
|
||||
|
||||
// The planner returns a plan, consisting of a single function
|
||||
// to execute and achieve the goal requested.
|
||||
var plan = planner.createPlanAsync(goal).block();
|
||||
|
||||
// Show the result, which should match the given goal
|
||||
System.out.println(plan.getName());
|
||||
|
||||
System.out.println(plan.invokeAsync(goal).block().getResult());
|
||||
|
||||
/* Output:
|
||||
*
|
||||
* Cleopatra was a queen
|
||||
* But she didn't act like one
|
||||
* She was more like a teen
|
||||
|
||||
* She was always on the scene
|
||||
* And she loved to be seen
|
||||
* But she didn't have a queenly bone in her body
|
||||
*/
|
||||
}
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.microsoft.semantickernel.GPT3Tokenizer;
|
||||
|
||||
/**
|
||||
* Demonstrates how to count tokens using GPT tokenizer. The number of tokens affects
|
||||
* API calls cost and each model has a maximum amount of tokens it can process and generate.
|
||||
* This example is specific to OpenAI models, which use the tokenization described here:
|
||||
* <a href="https://platform.openai.com/tokenizer">OpenAI tokenizer</a>
|
||||
* If you use Semantic Kernel with other models, the tokenization logic is most probably different,
|
||||
* and you should not use the GPT tokenizer.
|
||||
*/
|
||||
public class Example29_Tokenizer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Example 1
|
||||
String sentence = "Some text on one line";
|
||||
int tokenCount = GPT3Tokenizer.encode(sentence).size();
|
||||
|
||||
System.out.println("---");
|
||||
System.out.println(sentence);
|
||||
System.out.println("Tokens: " + tokenCount);
|
||||
System.out.println("---\n\n");
|
||||
|
||||
// Example 2
|
||||
sentence = "⭐⭐";
|
||||
tokenCount = GPT3Tokenizer.encode(sentence).size();
|
||||
|
||||
System.out.println("The following example contains emojis which require several tokens.");
|
||||
System.out.println("---");
|
||||
System.out.println(sentence);
|
||||
System.out.println("Tokens: " + tokenCount);
|
||||
System.out.println("---\n\n");
|
||||
|
||||
// Example 3
|
||||
sentence = "Some text on\ntwo lines";
|
||||
tokenCount = GPT3Tokenizer.encode(sentence).size();
|
||||
|
||||
System.out.println("The following example uses Unix '\\n' line separator.");
|
||||
System.out.println("---");
|
||||
System.out.println(sentence);
|
||||
System.out.println("Tokens: " + tokenCount);
|
||||
System.out.println("---\n\n");
|
||||
|
||||
// Example 4
|
||||
sentence = "Some text on\r\ntwo lines";
|
||||
tokenCount = GPT3Tokenizer.encode(sentence).size();
|
||||
|
||||
System.out.println("The following example uses Windows '\\r\\n' line separator.");
|
||||
System.out.println("---");
|
||||
System.out.println(sentence);
|
||||
System.out.println("Tokens: " + tokenCount);
|
||||
System.out.println("---\n\n");
|
||||
|
||||
/*
|
||||
Output:
|
||||
---
|
||||
Some text on one line
|
||||
Tokens: 5
|
||||
---
|
||||
|
||||
|
||||
The following example contains emojis which require several tokens.
|
||||
---
|
||||
⭐⭐
|
||||
Tokens: 6
|
||||
---
|
||||
|
||||
|
||||
The following example uses Unix '\n' line separator.
|
||||
---
|
||||
Some text on
|
||||
two lines
|
||||
Tokens: 6
|
||||
---
|
||||
|
||||
|
||||
The following example uses Windows '\r\n' line separator.
|
||||
---
|
||||
Some text on
|
||||
two lines
|
||||
Tokens: 7
|
||||
---
|
||||
*/
|
||||
}
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
|
||||
import static com.microsoft.semantickernel.chatcompletion.ChatHistory.AuthorRoles.Assistant;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletion;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import java.util.function.BiFunction;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Demonstrates how to use Semantic Kernel with Text Completion as streaming
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example33_StreamingChat {
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
StartStreamingChatAsync();
|
||||
}
|
||||
|
||||
private static void StartStreamingChatAsync() throws ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
|
||||
ChatCompletion chatCompletion = SKBuilders.chatCompletion()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId("gpt-35-turbo")
|
||||
.build();
|
||||
|
||||
System.out.println("Chat content:");
|
||||
System.out.println("------------------------");
|
||||
|
||||
var chatHistory = chatCompletion.createNewChat("You are a librarian, expert about books");
|
||||
messageOutput(chatHistory);
|
||||
|
||||
// First user message
|
||||
chatHistory.addMessage(ChatHistory.AuthorRoles.User, "Hi, I'm looking for book suggestions");
|
||||
messageOutput(chatHistory);
|
||||
|
||||
// First bot assistant message
|
||||
streamMessageOutputAsync(chatCompletion, chatHistory, Assistant);
|
||||
|
||||
// Second user message
|
||||
chatHistory.addMessage(ChatHistory.AuthorRoles.User, "I love history and philosophy, I'd like to learn something new about Greece, any suggestion?");
|
||||
messageOutput(chatHistory);
|
||||
|
||||
// Second bot assistant message
|
||||
streamMessageOutputAsync(chatCompletion, chatHistory, Assistant);
|
||||
}
|
||||
|
||||
private static void streamMessageOutputAsync(ChatCompletion chatGPT, ChatHistory chatHistory, ChatHistory.AuthorRoles authorRole) {
|
||||
System.out.println(authorRole.name() + ": ");
|
||||
|
||||
BiFunction<String, String, String> agg = (o, o2) -> o + o2;
|
||||
|
||||
Mono<String> mono = chatGPT
|
||||
.generateMessageStream(chatHistory, null)
|
||||
.reduce("", agg);
|
||||
|
||||
String fullMessage = mono.block();
|
||||
System.out.println(fullMessage);
|
||||
System.out.println("\n------------------------");
|
||||
chatHistory.addMessage(authorRole, fullMessage);
|
||||
}
|
||||
|
||||
private static void messageOutput(ChatHistory chatHistory) {
|
||||
var message = chatHistory.getMessages().get(chatHistory.getMessages().size() - 1);
|
||||
|
||||
System.out.println(message.getAuthorRoles().name() + " " + message.getContent());
|
||||
System.out.println("------------------------");
|
||||
}
|
||||
}
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
// Copyright (c) Microsoft. All rights reserved.
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.coreskills.TimeSkill;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.planner.stepwiseplanner.DefaultStepwisePlanner;
|
||||
import com.microsoft.semantickernel.planner.stepwiseplanner.StepwisePlanner;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import com.microsoft.semantickernel.textcompletion.TextCompletion;
|
||||
import java.util.Locale;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* Demonstrates the <a href=
|
||||
* "https://devblogs.microsoft.com/semantic-kernel/semantic-kernel-planners-stepwise-planner/">
|
||||
* Stepwise Planner</a>
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class Example51_StepwisePlanner {
|
||||
|
||||
// Fake a search engine skill so that users do not need to have a search engine API key to run this example
|
||||
public static class WebSearchEngineSkill {
|
||||
|
||||
@DefineSKFunction(description = "Perform a web search.", name = "search")
|
||||
public Mono<String> search(
|
||||
@SKFunctionParameters(description = "Text to search for", name = "query")
|
||||
String input,
|
||||
@SKFunctionParameters(description = "Number of results", name = "count", defaultValue = "1", type = Integer.class)
|
||||
Integer count,
|
||||
@SKFunctionParameters(description = "Number of results to skip", name = "offset", defaultValue = "0", type = Integer.class)
|
||||
Integer offset) {
|
||||
|
||||
String question = input.toLowerCase(Locale.ROOT);
|
||||
|
||||
if (question.contains("year")) {
|
||||
return Mono.just("1930");
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unable to find answer to question: " + input);
|
||||
}
|
||||
}
|
||||
|
||||
// Fake a calculator
|
||||
public static class AdvancedCalculator {
|
||||
|
||||
@DefineSKFunction(description = "Useful for getting the result of a non-trivial math expression.", name = "Calculator")
|
||||
public Mono<String> Calculator(
|
||||
@SKFunctionParameters(description = "A valid mathematical expression that could be executed by a calculator capable of more advanced math functions like sin/cosine/floor.", name = "input")
|
||||
String input) {
|
||||
if ("1930/2".equals(input)) {
|
||||
return Mono.just("965");
|
||||
} else {
|
||||
return Mono.error(new RuntimeException("Unknown calculation"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ConfigurationException {
|
||||
|
||||
String[] questions = new String[]{
|
||||
"What year is the first world cup divided by 2",
|
||||
};
|
||||
|
||||
for (String question : questions) {
|
||||
System.out.println("Result: " + runChatCompletion(question).block().getResult());
|
||||
|
||||
// Currently due to token limits, not supporting text completion
|
||||
//System.out.println("Result: " + runTextCompletion(question).block().getResult());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Mono<SKContext> runTextCompletion(String question) throws ConfigurationException {
|
||||
System.out.println("RunTextCompletion");
|
||||
var kernel = getKernel(false);
|
||||
return runWithQuestion(kernel, question);
|
||||
}
|
||||
|
||||
private static Mono<SKContext> runChatCompletion(String question) throws ConfigurationException {
|
||||
System.out.println("RunChatCompletion");
|
||||
var kernel = getKernel(true);
|
||||
return runWithQuestion(kernel, question);
|
||||
}
|
||||
|
||||
private static Mono<SKContext> runWithQuestion(Kernel kernel, String question) {
|
||||
var webSearchEngineSkill = new WebSearchEngineSkill();
|
||||
|
||||
kernel.importSkill(webSearchEngineSkill, "WebSearch");
|
||||
kernel.importSkill(new AdvancedCalculator(), "AdvancedCalculator");
|
||||
kernel.importSkill(new TimeSkill(), "time");
|
||||
|
||||
System.out.println("*****************************************************");
|
||||
System.out.println("Question: " + question);
|
||||
|
||||
StepwisePlanner planner = new DefaultStepwisePlanner(kernel, null, null, null);
|
||||
|
||||
var plan = planner.createPlan(question);
|
||||
|
||||
return plan.invokeAsync(SKBuilders.context().withKernel(kernel).build());
|
||||
}
|
||||
|
||||
private static Kernel getKernel(boolean useChat) throws ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
TextCompletion textCompletion;
|
||||
|
||||
if (useChat) {
|
||||
textCompletion = SKBuilders.chatCompletion()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId("gpt-35-turbo")
|
||||
.build();
|
||||
|
||||
} else {
|
||||
textCompletion = SKBuilders.textCompletion()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId("text-davinci-003")
|
||||
.build();
|
||||
}
|
||||
|
||||
return SKBuilders.kernel()
|
||||
.withDefaultAIService(textCompletion)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Run all the syntax examples.
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class RunAll {
|
||||
public interface MainMethod {
|
||||
void run(String[] args) throws Exception;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<MainMethod> mains = Arrays.asList(
|
||||
Example01_NativeFunctions::main,
|
||||
Example02_Pipeline::main,
|
||||
Example03_Variables::main,
|
||||
Example04_CombineLLMPromptsAndNativeCode::main,
|
||||
Example05_InlineFunctionDefinition::main,
|
||||
Example06_TemplateLanguage::main,
|
||||
Example08_RetryHandler::main,
|
||||
Example09_FunctionTypes::main,
|
||||
Example12_SequentialPlanner::main,
|
||||
Example13_ConversationSummarySkill::main,
|
||||
Example14_SemanticMemory::main,
|
||||
Example15_MemorySkill::main,
|
||||
Example17_ChatGPT::main,
|
||||
Example25_ReadOnlyMemoryStore::main,
|
||||
Example28_ActionPlanner::main,
|
||||
Example29_Tokenizer::main,
|
||||
Example33_StreamingChat::main,
|
||||
Example51_StepwisePlanner::main
|
||||
);
|
||||
|
||||
mains.forEach(mainMethod -> {
|
||||
try {
|
||||
mainMethod.run(args);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
-30
@@ -1,30 +0,0 @@
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class SampleSkillsUtil {
|
||||
|
||||
public static final String SAMPLES_SKILLS_DIR = "samples/skills";
|
||||
|
||||
/**
|
||||
* Detects the location of the sample skill directory by searching up til the top of the repository.
|
||||
*/
|
||||
public static String detectSkillDirLocation() {
|
||||
Path dir = Path.of(System.getProperty("user.dir"));
|
||||
|
||||
do {
|
||||
if (Files.isDirectory(dir.resolve(SAMPLES_SKILLS_DIR))) {
|
||||
return dir.resolve(SAMPLES_SKILLS_DIR).toFile().getAbsolutePath();
|
||||
}
|
||||
|
||||
if (Files.exists(dir.resolve(".gitignore"))) {
|
||||
// We've reached the root of the repo
|
||||
throw new RuntimeException("Could not find skill directory");
|
||||
}
|
||||
|
||||
} while ((dir = dir.getParent()) != null);
|
||||
|
||||
throw new RuntimeException("Could not find skill directory");
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples.javaspecific;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Import a skill from resources.
|
||||
*/
|
||||
public class Java_Example01_ResourceLoading {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.build();
|
||||
|
||||
kernel.importSkillFromResources(
|
||||
"Plugins",
|
||||
"ExamplePlugins",
|
||||
"ExampleFunction",
|
||||
Java_Example01_ResourceLoading.class
|
||||
);
|
||||
|
||||
SKFunction<?> function = kernel.getSkills().getFunctions("ExamplePlugins").getFunction("ExampleFunction");
|
||||
|
||||
System.out.println("Loaded function: " + function.getDescription());
|
||||
|
||||
|
||||
kernel.importSkillFromResources(
|
||||
"Plugins",
|
||||
"ExamplePlugins",
|
||||
"ExampleFunctionRoot"
|
||||
);
|
||||
function = kernel.getSkills().getFunctions("ExamplePlugins").getFunction("ExampleFunctionRoot");
|
||||
|
||||
System.out.println("Loaded function from classpath root: " + function.getDescription());
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
package com.microsoft.semantickernel.samples.syntaxexamples.javaspecific;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.SamplesConfig;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.planner.sequentialplanner.SequentialPlanner;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionInputAttribute;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Using Sequential Planner to take the input as a question and answer it finding any information needed.
|
||||
* <p>
|
||||
* See <a href=
|
||||
* "https://devblogs.microsoft.com/semantic-kernel/semantic-kernel-planners-sequential-planner/">
|
||||
* Semantic Kernel Planners: Sequential Planner</a>
|
||||
* <p>
|
||||
* Refer to the <a href=
|
||||
* "https://github.com/microsoft/semantic-kernel/blob/experimental-java/java/samples/sample-code/README.md">
|
||||
* README</a> for configuring your environment to run the examples.
|
||||
*/
|
||||
public class SequentialPlanner_AnswerQuestion {
|
||||
|
||||
public static class InformationFinder {
|
||||
@DefineSKFunction(
|
||||
name = "Search",
|
||||
description = "Returns information relevant to answering a given query."
|
||||
)
|
||||
public String search(
|
||||
@SKFunctionInputAttribute(description = "The query to answer.")
|
||||
String query) {
|
||||
return """
|
||||
- The Eiffel Tower is in Paris.
|
||||
- The Eiffel Tower is made of metal.
|
||||
- The Eiffel Tower is 324 meters tall.
|
||||
""".stripIndent();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, ConfigurationException {
|
||||
OpenAIAsyncClient client = SamplesConfig.getClient();
|
||||
var kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(SKBuilders.textCompletion()
|
||||
.withModelId("text-davinci-003")
|
||||
.withOpenAIClient(client)
|
||||
.build())
|
||||
.build();
|
||||
|
||||
|
||||
kernel.importSkillFromResources(
|
||||
"Plugins",
|
||||
"Answer",
|
||||
"AnswerQuestion",
|
||||
SequentialPlanner_AnswerQuestion.class
|
||||
);
|
||||
|
||||
kernel.importSkill(new InformationFinder(), "InformationFinder");
|
||||
|
||||
String prompt;
|
||||
try (InputStream altprompt = SequentialPlanner_AnswerQuestion.class.getResourceAsStream("require_context_variable_planner_prompt.txt")) {
|
||||
prompt = new String(altprompt.readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
var planner = new SequentialPlanner(kernel, null, prompt);
|
||||
|
||||
var plan = planner.createPlanAsync("Take the input as a question and answer it finding any information needed.").block();
|
||||
|
||||
System.out.println(plan.toPlanString());
|
||||
|
||||
SKContext response = plan.invokeAsync("Where is the Eiffel Tower?").block();
|
||||
|
||||
System.out.println("========================================");
|
||||
System.out.println("Answer is: " + response.getResult());
|
||||
System.out.println("Sources used to answer this question: " + response.getVariables().get("sources"));
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,18 @@
|
||||
<artifactId>semantickernel-samples-guice</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-bom</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
|
||||
+6
-6
@@ -2,24 +2,24 @@
|
||||
package com.microsoft.semantickernel.guice;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionSKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptConfig;
|
||||
import com.microsoft.semantickernel.textcompletion.CompletionKernelFunction;
|
||||
import jakarta.inject.Inject;
|
||||
|
||||
public interface CompletionFunctionFactory {
|
||||
|
||||
CompletionSKFunction createFunction(
|
||||
String prompt, String name, PromptTemplateConfig.CompletionConfig completionConfig);
|
||||
CompletionKernelFunction createFunction(
|
||||
String prompt, String name, PromptConfig.CompletionConfig completionConfig);
|
||||
|
||||
class CompletionFunctionFactoryImpl implements CompletionFunctionFactory {
|
||||
@Inject
|
||||
private Kernel kernel;
|
||||
|
||||
@Override
|
||||
public CompletionSKFunction createFunction(
|
||||
public CompletionKernelFunction createFunction(
|
||||
String prompt,
|
||||
String name,
|
||||
PromptTemplateConfig.CompletionConfig completionConfig) {
|
||||
PromptConfig.CompletionConfig completionConfig) {
|
||||
return kernel.getSemanticFunctionBuilder()
|
||||
.withPromptTemplate(prompt)
|
||||
.withFunctionName(name)
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@ import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
import com.microsoft.semantickernel.orchestration.SKContext;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptTemplateConfig;
|
||||
import com.microsoft.semantickernel.semanticfunctions.PromptConfig;
|
||||
|
||||
public class CompletionFunctionExample {
|
||||
|
||||
@@ -64,7 +64,7 @@ public class CompletionFunctionExample {
|
||||
.createFunction(
|
||||
prompt,
|
||||
"summarize",
|
||||
new PromptTemplateConfig.CompletionConfig(
|
||||
new PromptConfig.CompletionConfig(
|
||||
0.2, 0.5, 0, 0, 2000))
|
||||
.invokeAsync(text)
|
||||
.block();
|
||||
|
||||
@@ -10,15 +10,8 @@
|
||||
<version>1.0.0-alpha.1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
||||
<artifactId>01-SimpleChat</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Map;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.azure.ai.openai.OpenAIClientBuilder;
|
||||
import com.azure.core.credential.KeyCredential;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.KernelResult;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletion;
|
||||
import com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletionService;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.semanticfunctions.SemanticFunction;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplateEngine;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunction;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunctionYaml;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.ContextVariable;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.KernelArguments;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
||||
final static String GPT_35_DEPLOYMENT_NAME = System.getenv("GPT_35_DEPLOYMENT_NAME");
|
||||
final static String GPT_4_DEPLOYMENT_NAME = System.getenv("GPT_4_DEPLOYMENT_NAME");
|
||||
final static String AZURE_OPENAI_ENDPOINT = System.getenv("AZURE_OPENAI_ENDPOINT");
|
||||
final static String AZURE_OPENAI_API_KEY = System.getenv("AZURE_OPENAI_API_KEY");
|
||||
final static String CURRENT_DIRECTORY = System.getProperty("user.dir");
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
OpenAIAsyncClient client = new OpenAIClientBuilder()
|
||||
@@ -31,26 +32,28 @@ public class Main {
|
||||
.endpoint(AZURE_OPENAI_ENDPOINT)
|
||||
.buildAsyncClient();
|
||||
|
||||
ChatCompletion<ChatHistory> gpt35Turbo = ChatCompletion.builder()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId(GPT_35_DEPLOYMENT_NAME)
|
||||
.build();
|
||||
ChatCompletionService gpt35Turbo = AzureOpenAIChatCompletion.builder()
|
||||
.withOpenAIAsyncClient(client)
|
||||
.withModelId(GPT_35_DEPLOYMENT_NAME != null ? GPT_35_DEPLOYMENT_NAME : "gpt-35-turbo")
|
||||
.build();
|
||||
|
||||
/*
|
||||
ChatCompletion<ChatHistory> gpt4 = ChatCompletion.builder()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId(GPT_4_DEPLOYMENT_NAME)
|
||||
.build();
|
||||
.withOpenAIClient(client)
|
||||
.withModelId(GPT_4_DEPLOYMENT_NAME != null ? GPT_4_DEPLOYMENT_NAME : "gpt-4")
|
||||
.build();
|
||||
*/
|
||||
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(gpt35Turbo)
|
||||
.withDefaultAIService(gpt4)
|
||||
.withPromptTemplateEngine(new HandlebarsPromptTemplateEngine())
|
||||
.build();
|
||||
.withDefaultAIService(ChatCompletionService.class, gpt35Turbo)
|
||||
.withPromptTemplateEngine(new HandlebarsPromptTemplate())
|
||||
.build();
|
||||
|
||||
// Initialize the required functions and services for the kernel
|
||||
SemanticFunction chatFunction = SemanticFunction.fromYaml("Plugins/ChatPlugin/SimpleChat.prompt.yaml");
|
||||
KernelFunction chatFunction = KernelFunctionYaml.fromYaml(
|
||||
Path.of("Plugins/ChatPlugin/SimpleChat.prompt.yaml"));
|
||||
|
||||
ChatHistory chatHistory = gpt35Turbo.createNewChat();
|
||||
ChatHistory chatHistory = new ChatHistory();
|
||||
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
|
||||
while (true) {
|
||||
@@ -58,23 +61,20 @@ public class Main {
|
||||
String input = bf.readLine();
|
||||
chatHistory.addUserMessage(input);
|
||||
|
||||
KernelResult result = kernel.runAsync(
|
||||
true,
|
||||
ContextVariables.builder().withVariable("messages", chatHistory).build(),
|
||||
chatFunction
|
||||
).block();
|
||||
ContextVariable<String> message = kernel
|
||||
.invokeAsync(
|
||||
chatFunction,
|
||||
KernelArguments
|
||||
.builder()
|
||||
.withVariable("messages", chatHistory)
|
||||
.build(),
|
||||
String.class
|
||||
)
|
||||
.block();
|
||||
|
||||
System.out.print("Assistant > ");
|
||||
result.functionResults().forEach(
|
||||
functionResult -> {
|
||||
functionResult.<String>getStreamingValueAsync().subscribe(
|
||||
message -> System.out.print(message)
|
||||
);
|
||||
|
||||
String message = functionResult.<String>getValue();
|
||||
chatHistory.addAssistantMessage(message);
|
||||
}
|
||||
);
|
||||
System.out.println(message.getValue());
|
||||
chatHistory.addAssistantMessage(message.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-3
@@ -20,7 +20,17 @@ output_variable:
|
||||
type: string
|
||||
description: The response from the assistant.
|
||||
execution_settings:
|
||||
- model_id_pattern: ^gpt-4
|
||||
- model_id: gpt-3.5-turbo
|
||||
temperature: 0.3
|
||||
top_p: 0.0
|
||||
presence_penalty: 0.0
|
||||
frequency_penalty: 0.0
|
||||
max_tokens: 256
|
||||
stop_sequences: [ ]
|
||||
- model_id: gpt-4
|
||||
temperature: 0.7
|
||||
- model_id_pattern: ^gpt-3\.?5-turbo
|
||||
temperature: 0.3
|
||||
top_p: 0.0
|
||||
presence_penalty: 0.0
|
||||
frequency_penalty: 0.0
|
||||
max_tokens: 256
|
||||
stop_sequences: [ ]
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.chatcompletion.AuthorRole;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletionService;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.chatcompletion.StreamingChatMessageContent;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunction;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunctionYaml;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.KernelArguments;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class SimpleChatTest {
|
||||
|
||||
record Message(String matcher, String role, String content) {
|
||||
|
||||
}
|
||||
|
||||
private static ChatCompletionService mockService(List<Message> messages) {
|
||||
ChatCompletionService gpt35Turbo = Mockito.mock(ChatCompletionService.class);
|
||||
|
||||
for (Message message : messages) {
|
||||
Mockito.when(gpt35Turbo.getStreamingChatMessageContentsAsync(
|
||||
Mockito.<String>argThat(
|
||||
argument -> {
|
||||
if (argument != null && argument.contains(message.matcher)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}),
|
||||
Mockito.any(),
|
||||
Mockito.any()))
|
||||
.thenReturn(Flux.just(
|
||||
new StreamingChatMessageContent(AuthorRole.ASSISTANT, message.content())));
|
||||
}
|
||||
return gpt35Turbo;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runSimpleChatTest() throws IOException {
|
||||
List<Message> messages = Arrays.asList(
|
||||
new Message("Is 4 prime", "assistant", "Yes 4 is prime"),
|
||||
new Message("What is the capital of France", "assistant", "Paris")
|
||||
);
|
||||
|
||||
ChatCompletionService gpt35Turbo = mockService(messages);
|
||||
|
||||
execute(gpt35Turbo, messages);
|
||||
}
|
||||
|
||||
|
||||
private static void execute(ChatCompletionService gpt35Turbo, List<Message> messages)
|
||||
throws IOException {
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(ChatCompletionService.class, gpt35Turbo)
|
||||
.withPromptTemplateEngine(new HandlebarsPromptTemplate())
|
||||
.build();
|
||||
|
||||
// Initialize the required functions and services for the kernel
|
||||
KernelFunction chatFunction = KernelFunctionYaml.fromYaml(
|
||||
Path.of("Plugins/ChatPlugin/SimpleChat.prompt.yaml"));
|
||||
|
||||
ChatHistory chatHistory = new ChatHistory();
|
||||
|
||||
messages.forEach(message -> {
|
||||
chatHistory.addUserMessage(message.matcher);
|
||||
|
||||
List<String> result = kernel
|
||||
.invokeStreamingAsync(
|
||||
chatFunction,
|
||||
KernelArguments
|
||||
.builder()
|
||||
.withVariable("messages", chatHistory)
|
||||
.build(),
|
||||
String.class
|
||||
)
|
||||
.collectList()
|
||||
.block();
|
||||
|
||||
result.forEach(
|
||||
functionResult -> {
|
||||
Assertions.assertEquals(message.content(), functionResult);
|
||||
chatHistory.addAssistantMessage(functionResult.toString());
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,5 @@
|
||||
|
||||
<artifactId>02-PersonaChat</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-core</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -1,64 +1,56 @@
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.azure.ai.openai.OpenAIClientBuilder;
|
||||
import com.azure.core.credential.KeyCredential;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.KernelResult;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletion;
|
||||
import com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletionService;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import com.microsoft.semantickernel.semanticfunctions.SemanticFunction;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplateEngine;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunction;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunctionYaml;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.KernelArguments;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
||||
final static String GPT_35_DEPLOYMENT_NAME = System.getenv("GPT_35_DEPLOYMENT_NAME");
|
||||
final static String GPT_4_DEPLOYMENT_NAME = System.getenv("GPT_4_DEPLOYMENT_NAME");
|
||||
final static String AZURE_OPENAI_ENDPOINT = System.getenv("AZURE_OPENAI_ENDPOINT");
|
||||
final static String AZURE_OPENAI_API_KEY = System.getenv("AZURE_OPENAI_API_KEY");
|
||||
final static String CURRENT_DIRECTORY = System.getProperty("user.dir");
|
||||
|
||||
|
||||
public static void main(String[] args) throws ConfigurationException, IOException {
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
OpenAIAsyncClient client = new OpenAIClientBuilder()
|
||||
.credential(new KeyCredential(AZURE_OPENAI_API_KEY))
|
||||
.endpoint(AZURE_OPENAI_ENDPOINT)
|
||||
.buildAsyncClient();
|
||||
|
||||
|
||||
// Initialize the required functions and services for the kernel
|
||||
SKFunction chatFunction = SemanticFunction.fromYaml("Plugins/ChatPlugin/PersonaChat.prompt.yaml");
|
||||
KernelFunction chatFunction = KernelFunctionYaml.fromYaml(
|
||||
Path.of("Plugins/ChatPlugin/PersonaChat.prompt.yaml"));
|
||||
|
||||
ChatCompletion<ChatHistory> gpt35Turbo = ChatCompletion.builder()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId(GPT_35_DEPLOYMENT_NAME)
|
||||
ChatCompletionService gpt35Turbo = AzureOpenAIChatCompletion.builder()
|
||||
.withOpenAIAsyncClient(client)
|
||||
.withModelId(GPT_35_DEPLOYMENT_NAME != null ? GPT_35_DEPLOYMENT_NAME : "gpt-35-turbo")
|
||||
.build();
|
||||
|
||||
ChatCompletion<ChatHistory> gpt4 = ChatCompletion.builder()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId(GPT_4_DEPLOYMENT_NAME)
|
||||
.build();
|
||||
|
||||
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(gpt35Turbo)
|
||||
.withDefaultAIService(gpt4)
|
||||
.withPromptTemplateEngine(new HandlebarsPromptTemplateEngine())
|
||||
.withDefaultAIService(ChatCompletionService.class, gpt35Turbo)
|
||||
.withPromptTemplateEngine(new HandlebarsPromptTemplate())
|
||||
.build();
|
||||
|
||||
ChatHistory chatHistory = gpt35Turbo.createNewChat();
|
||||
ChatHistory chatHistory = new ChatHistory();
|
||||
|
||||
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
System.out.print("\nUser > ");
|
||||
String input = bf.readLine();
|
||||
chatHistory.addUserMessage(input);
|
||||
@@ -66,25 +58,27 @@ public class Main {
|
||||
// Run the chat function
|
||||
// The persona chat function uses the persona variable to set the persona of the chat using a system message
|
||||
// See Plugins/ChatPlugin/PersonaChat.prompt.yaml for the full prompt
|
||||
KernelResult result = kernel.runAsync(
|
||||
true, // streaming
|
||||
ContextVariables.builder()
|
||||
.withVariable("messages", chatHistory)
|
||||
.withVariable("persona", "You are a snarky (yet helpful) teenage assistant. Make sure to use hip slang in every response.")
|
||||
.build(),
|
||||
chatFunction
|
||||
).block();
|
||||
List<String> result = kernel.invokeStreamingAsync(
|
||||
chatFunction,
|
||||
KernelArguments
|
||||
.builder()
|
||||
.withVariable("messages", chatHistory)
|
||||
.withVariable("persona",
|
||||
"You are a snarky (yet helpful) teenage assistant. Make sure to use hip slang in every response.")
|
||||
.build(),
|
||||
String.class
|
||||
)
|
||||
.collectList()
|
||||
.block();
|
||||
|
||||
System.out.print("Assistant > ");
|
||||
result.functionResults().forEach(
|
||||
functionResult -> {
|
||||
functionResult.<String>getStreamingValueAsync().subscribe(
|
||||
message -> System.out.print(message)
|
||||
);
|
||||
String message = functionResult.<String>getValueAsync().block();
|
||||
chatHistory.addAssistantMessage(message);
|
||||
}
|
||||
);
|
||||
}
|
||||
result
|
||||
.forEach(
|
||||
message -> {
|
||||
System.out.print(message);
|
||||
chatHistory.addAssistantMessage(message);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-4
@@ -1,5 +1,5 @@
|
||||
name: PersonaChat
|
||||
template: |
|
||||
template: |
|
||||
{{#message role="system"}}
|
||||
{{persona}}
|
||||
Do not answer with XML or any format.
|
||||
@@ -26,7 +26,17 @@ output_variable:
|
||||
type: string
|
||||
description: The response from the assistant.
|
||||
execution_settings:
|
||||
- model_id_pattern: ^gpt-4
|
||||
- model_id: gpt-3.5-turbo
|
||||
temperature: 0.3
|
||||
top_p: 0.0
|
||||
presence_penalty: 0.0
|
||||
frequency_penalty: 0.0
|
||||
max_tokens: 256
|
||||
stop_sequences: [ ]
|
||||
- model_id: gpt-4
|
||||
temperature: 0.7
|
||||
- model_id_pattern: ^gpt-3\.?5-turbo
|
||||
temperature: 0.3
|
||||
top_p: 0.0
|
||||
presence_penalty: 0.0
|
||||
frequency_penalty: 0.0
|
||||
max_tokens: 256
|
||||
stop_sequences: [ ]
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.chatcompletion.AuthorRole;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletionService;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.chatcompletion.StreamingChatMessageContent;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunction;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunctionYaml;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.KernelArguments;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class PersonaChatTest {
|
||||
|
||||
record Message(String matcher, String role, String content) {
|
||||
|
||||
}
|
||||
|
||||
private static ChatCompletionService mockService(List<Message> messages) {
|
||||
ChatCompletionService gpt35Turbo = Mockito.mock(ChatCompletionService.class);
|
||||
|
||||
for (Message message : messages) {
|
||||
Mockito.when(gpt35Turbo.getStreamingChatMessageContentsAsync(
|
||||
Mockito.<String>argThat(
|
||||
argument -> {
|
||||
if (argument != null && argument.contains(message.matcher)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}),
|
||||
Mockito.any(),
|
||||
Mockito.any()))
|
||||
.thenReturn(Flux.just(new StreamingChatMessageContent(
|
||||
AuthorRole.ASSISTANT, message.content())));
|
||||
}
|
||||
return gpt35Turbo;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runSimpleChatTest() throws IOException {
|
||||
List<Message> messages = Arrays.asList(
|
||||
new Message("Is 4 prime", "assistant", "Yes 4 is prime"),
|
||||
new Message("What is the capital of France", "assistant", "Paris")
|
||||
);
|
||||
|
||||
ChatCompletionService gpt35Turbo = mockService(messages);
|
||||
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(ChatCompletionService.class, gpt35Turbo)
|
||||
.withPromptTemplateEngine(new HandlebarsPromptTemplate())
|
||||
.build();
|
||||
|
||||
// Initialize the required functions and services for the kernel
|
||||
KernelFunction chatFunction = KernelFunctionYaml.fromYaml(
|
||||
Path.of("Plugins/ChatPlugin/PersonaChat.prompt.yaml"));
|
||||
|
||||
ChatHistory chatHistory = new ChatHistory();
|
||||
|
||||
messages.forEach(message -> {
|
||||
chatHistory.addUserMessage(message.matcher);
|
||||
|
||||
List<String> result = kernel
|
||||
.invokeStreamingAsync(
|
||||
chatFunction,
|
||||
KernelArguments
|
||||
.builder()
|
||||
.withVariable("messages", chatHistory)
|
||||
.withVariable("persona",
|
||||
"You are a snarky (yet helpful) teenage assistant. Make sure to use hip slang in every response.")
|
||||
.build(),
|
||||
String.class
|
||||
)
|
||||
.collectList()
|
||||
.block();
|
||||
|
||||
result
|
||||
.forEach(
|
||||
functionResult -> {
|
||||
Assertions.assertEquals(message.content(), functionResult);
|
||||
chatHistory.addAssistantMessage(functionResult.toString());
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -14,20 +14,5 @@
|
||||
|
||||
<artifactId>03-SimpleRag</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-plugin-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.azure.ai.openai.OpenAIAsyncClient;
|
||||
import com.azure.ai.openai.OpenAIClientBuilder;
|
||||
import com.azure.core.credential.KeyCredential;
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.KernelResult;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletion;
|
||||
import com.microsoft.semantickernel.chatcompletion.AzureOpenAIChatCompletion;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletionService;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.exceptions.ConfigurationException;
|
||||
import com.microsoft.semantickernel.nativefunction.NativeFunction;
|
||||
import com.microsoft.semantickernel.orchestration.ContextVariables;
|
||||
import com.microsoft.semantickernel.orchestration.SKFunction;
|
||||
import com.microsoft.semantickernel.plugin.Plugin;
|
||||
import com.microsoft.semantickernel.semanticfunctions.SemanticFunction;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplateEngine;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunction;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunctionYaml;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.KernelArguments;
|
||||
import com.microsoft.semantickernel.plugin.KernelPlugin;
|
||||
import com.microsoft.semantickernel.plugin.KernelPluginFactory;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import plugins.searchplugin.Search;
|
||||
|
||||
public class Main {
|
||||
|
||||
|
||||
final static String GPT_35_DEPLOYMENT_NAME = System.getenv("GPT_35_DEPLOYMENT_NAME");
|
||||
final static String GPT_4_DEPLOYMENT_NAME = System.getenv("GPT_4_DEPLOYMENT_NAME");
|
||||
final static String AZURE_OPENAI_ENDPOINT = System.getenv("AZURE_OPENAI_ENDPOINT");
|
||||
final static String AZURE_OPENAI_API_KEY = System.getenv("AZURE_OPENAI_API_KEY");
|
||||
final static String BING_API_KEY = System.getenv("BING_API_KEY");
|
||||
final static String CURRENT_DIRECTORY = System.getProperty("user.dir");
|
||||
|
||||
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
OpenAIAsyncClient client = new OpenAIClientBuilder()
|
||||
@@ -35,61 +35,53 @@ public class Main {
|
||||
.endpoint(AZURE_OPENAI_ENDPOINT)
|
||||
.buildAsyncClient();
|
||||
|
||||
|
||||
// Initialize the required functions and services for the kernel
|
||||
SKFunction chatFunction = SemanticFunction.fromYaml("Plugins/ChatPlugin/GroundedChat.prompt.yaml");
|
||||
KernelFunction chatFunction = KernelFunctionYaml.fromYaml(
|
||||
Path.of("Plugins/ChatPlugin/GroundedChat.prompt.yaml"));
|
||||
|
||||
ChatCompletion<ChatHistory> gpt35Turbo = ChatCompletion.builder()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId(GPT_35_DEPLOYMENT_NAME)
|
||||
ChatCompletionService gpt35Turbo = AzureOpenAIChatCompletion.builder()
|
||||
.withOpenAIAsyncClient(client)
|
||||
.withModelId(GPT_35_DEPLOYMENT_NAME != null ? GPT_35_DEPLOYMENT_NAME : "gpt-35-turbo")
|
||||
.build();
|
||||
|
||||
ChatCompletion<ChatHistory> gpt4 = ChatCompletion.builder()
|
||||
.withOpenAIClient(client)
|
||||
.withModelId(GPT_4_DEPLOYMENT_NAME)
|
||||
.build();
|
||||
|
||||
// Create the search plugin
|
||||
Plugin searchPlugin = new com.microsoft.semantickernel.plugin.Plugin(
|
||||
"Search",
|
||||
NativeFunction.getFunctionsFromObject(new Search(BING_API_KEY))
|
||||
);
|
||||
KernelPlugin searchPlugin = KernelPluginFactory.createFromObject(
|
||||
new Search(BING_API_KEY),
|
||||
"Search"
|
||||
);
|
||||
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(gpt35Turbo)
|
||||
.withDefaultAIService(gpt4)
|
||||
.withPromptTemplateEngine(new HandlebarsPromptTemplateEngine())
|
||||
.withDefaultAIService(ChatCompletionService.class, gpt35Turbo)
|
||||
.withPromptTemplateEngine(new HandlebarsPromptTemplate())
|
||||
.withPlugins(searchPlugin)
|
||||
.build();
|
||||
|
||||
ChatHistory chatHistory = gpt35Turbo.createNewChat();
|
||||
while(true)
|
||||
{
|
||||
ChatHistory chatHistory = new ChatHistory();
|
||||
while (true) {
|
||||
String input = System.console().readLine("User > ");
|
||||
chatHistory.addUserMessage(input);
|
||||
|
||||
// Run the chat function
|
||||
// The grounded chat function uses the search plugin to perform a Bing search to ground the response
|
||||
// See Plugins/ChatPlugin/GroundedChat.prompt.yaml for the full prompt
|
||||
KernelResult result = kernel.runAsync(
|
||||
true, // streaming
|
||||
ContextVariables.builder()
|
||||
.withVariable("messages", chatHistory)
|
||||
.withVariable("persona", "You are a snarky (yet helpful) teenage assistant. Make sure to use hip slang in every response.")
|
||||
.build(),
|
||||
chatFunction
|
||||
).block();
|
||||
List<String> result = kernel.invokeStreamingAsync(
|
||||
chatFunction,
|
||||
KernelArguments.builder()
|
||||
.withVariable("messages", chatHistory)
|
||||
.withVariable("persona",
|
||||
"You are a snarky (yet helpful) teenage assistant. Make sure to use hip slang in every response.")
|
||||
.build(),
|
||||
String.class
|
||||
).collectList()
|
||||
.block();
|
||||
|
||||
System.console().printf("Assistant > ");
|
||||
result.functionResults().forEach(
|
||||
result.forEach(
|
||||
functionResult -> {
|
||||
functionResult.<String>getStreamingValueAsync().subscribe(
|
||||
message -> System.console().printf(message)
|
||||
);
|
||||
String message = functionResult.<String>getValueAsync().block();
|
||||
chatHistory.addAssistantMessage(message);
|
||||
System.out.println(functionResult);
|
||||
chatHistory.addAssistantMessage(functionResult);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
package plugins.searchplugin;
|
||||
|
||||
import com.azure.core.http.HttpClient;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.DefineSKFunction;
|
||||
import com.microsoft.semantickernel.skilldefinition.annotations.SKFunctionParameters;
|
||||
import com.microsoft.semantickernel.plugin.annotations.DefineKernelFunction;
|
||||
import com.microsoft.semantickernel.plugin.annotations.KernelFunctionParameter;
|
||||
import com.microsoft.semantickernel.plugins.web.bing.BingConnector;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
public class Search {
|
||||
@@ -21,9 +20,9 @@ public class Search {
|
||||
this._bingConnector = new BingConnector(apiKey, httpClient);
|
||||
}
|
||||
|
||||
@DefineSKFunction(description="Searches Bing for the given query")
|
||||
@DefineKernelFunction(description="Searches Bing for the given query")
|
||||
public Mono<String> searchAsync(
|
||||
@SKFunctionParameters(description="The search query", name="query", type=String.class) String query
|
||||
@KernelFunctionParameter(description="The search query", name="query", type=String.class) String query
|
||||
){
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
+15
-5
@@ -28,10 +28,20 @@ input_variables:
|
||||
description: The history of the chat.
|
||||
is_required: true
|
||||
output_variable:
|
||||
type: string
|
||||
description: The response from the assistant.
|
||||
type: string
|
||||
description: The response from the assistant.
|
||||
execution_settings:
|
||||
- model_id_pattern: ^gpt-3\.?5-turbo
|
||||
- model_id: gpt-3.5-turbo
|
||||
temperature: 0.3
|
||||
- model_id_pattern: ^gpt-4
|
||||
temperature: 0.7
|
||||
top_p: 0.0
|
||||
presence_penalty: 0.0
|
||||
frequency_penalty: 0.0
|
||||
max_tokens: 256
|
||||
stop_sequences: [ ]
|
||||
- model_id: gpt-4
|
||||
temperature: 0.7
|
||||
top_p: 0.0
|
||||
presence_penalty: 0.0
|
||||
frequency_penalty: 0.0
|
||||
max_tokens: 256
|
||||
stop_sequences: [ ]
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
import com.microsoft.semantickernel.Kernel;
|
||||
import com.microsoft.semantickernel.SKBuilders;
|
||||
import com.microsoft.semantickernel.chatcompletion.AuthorRole;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatCompletionService;
|
||||
import com.microsoft.semantickernel.chatcompletion.ChatHistory;
|
||||
import com.microsoft.semantickernel.chatcompletion.StreamingChatMessageContent;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunction;
|
||||
import com.microsoft.semantickernel.orchestration.KernelFunctionYaml;
|
||||
import com.microsoft.semantickernel.orchestration.contextvariables.KernelArguments;
|
||||
import com.microsoft.semantickernel.plugin.KernelPlugin;
|
||||
import com.microsoft.semantickernel.plugin.KernelPluginFactory;
|
||||
import com.microsoft.semantickernel.templateengine.handlebars.HandlebarsPromptTemplate;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
import plugins.searchplugin.Search;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
public class SimpleRagTest {
|
||||
|
||||
record Message(String matcher, String role, String content) {
|
||||
|
||||
}
|
||||
|
||||
private static ChatCompletionService mockService(List<Message> messages) {
|
||||
ChatCompletionService gpt35Turbo = Mockito.mock(ChatCompletionService.class);
|
||||
|
||||
for (Message message : messages) {
|
||||
Mockito.when(gpt35Turbo.getStreamingChatMessageContentsAsync(
|
||||
Mockito.<String>argThat(
|
||||
argument -> {
|
||||
if (argument != null && argument.contains(message.matcher)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}),
|
||||
Mockito.any(),
|
||||
Mockito.any()))
|
||||
.thenReturn(Flux.just(
|
||||
new StreamingChatMessageContent(AuthorRole.ASSISTANT, message.content())));
|
||||
}
|
||||
return gpt35Turbo;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runSimpleChatTest() throws IOException {
|
||||
List<Message> messages = Arrays.asList(
|
||||
new Message("Is 4 prime", "assistant", "Yes 4 is prime"),
|
||||
new Message("What is the capital of France", "assistant", "Paris")
|
||||
);
|
||||
|
||||
// Initialize the required functions and services for the kernel
|
||||
KernelFunction chatFunction = KernelFunctionYaml.fromYaml(
|
||||
Path.of("Plugins/ChatPlugin/GroundedChat.prompt.yaml"));
|
||||
|
||||
ChatCompletionService gpt35Turbo = mockService(messages);
|
||||
|
||||
// Create the search plugin
|
||||
KernelPlugin searchPlugin = KernelPluginFactory.createFromObject(
|
||||
new Search(""),
|
||||
"Search"
|
||||
);
|
||||
|
||||
Kernel kernel = SKBuilders.kernel()
|
||||
.withDefaultAIService(ChatCompletionService.class, gpt35Turbo)
|
||||
.withPromptTemplateEngine(new HandlebarsPromptTemplate())
|
||||
.withPlugins(searchPlugin)
|
||||
.build();
|
||||
|
||||
ChatHistory chatHistory = new ChatHistory();
|
||||
|
||||
messages.forEach(message -> {
|
||||
chatHistory.addUserMessage(message.matcher);
|
||||
|
||||
// Run the chat function
|
||||
// The grounded chat function uses the search plugin to perform a Bing search to ground the response
|
||||
// See Plugins/ChatPlugin/GroundedChat.prompt.yaml for the full prompt
|
||||
List<String> result = kernel.invokeStreamingAsync(
|
||||
chatFunction,
|
||||
KernelArguments.builder()
|
||||
.withVariable("messages", chatHistory)
|
||||
.withVariable("persona",
|
||||
"You are a snarky (yet helpful) teenage assistant. Make sure to use hip slang in every response.")
|
||||
.build(),
|
||||
String.class
|
||||
).collectList()
|
||||
.block();
|
||||
|
||||
result
|
||||
.forEach(
|
||||
functionResult -> {
|
||||
Assertions.assertEquals(message.content(), functionResult);
|
||||
chatHistory.addAssistantMessage(functionResult.toString());
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -41,12 +41,12 @@ public class Main {
|
||||
SKFunction chatFunction = SemanticFunction.fromYaml("/Plugins/ChatPlugin/Chat.prompt.yaml");
|
||||
|
||||
ChatCompletion<ChatHistory> gpt35Turbo = ChatCompletion.builder()
|
||||
.withOpenAIClient(client)
|
||||
.withOpenAIAsyncClient(client)
|
||||
.withModelId(GPT_35_TURBO_DEPLOYMENT_NAME)
|
||||
.build();
|
||||
|
||||
ChatCompletion<ChatHistory> gpt4 = ChatCompletion.builder()
|
||||
.withOpenAIClient(client)
|
||||
.withOpenAIAsyncClient(client)
|
||||
.withModelId(GPT_4_DEPLOYMENT_NAME)
|
||||
.build();
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public class Main {
|
||||
.buildAsyncClient();
|
||||
|
||||
ChatCompletion<ChatHistory> gpt4Turbo = ChatCompletion.builder()
|
||||
.withOpenAIClient(client)
|
||||
.withOpenAIAsyncClient(client)
|
||||
.withModelId(GPT_4_DEPLOYMENT_NAME)
|
||||
.build();
|
||||
|
||||
|
||||
+108
-54
@@ -1,17 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<!-- <parent>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>samples</artifactId>
|
||||
<version>1.0.0-alpha.1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent> -->
|
||||
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>sk-v1-samples</artifactId>
|
||||
<version>1.0.0-alpha.1-SNAPSHOT</version>
|
||||
|
||||
|
||||
<name>Semantic Kernel version 1 Samples</name>
|
||||
<description>Sample code for using the Semantic Kernel version 1 API</description>
|
||||
<packaging>pom</packaging>
|
||||
@@ -22,64 +17,123 @@
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
||||
<modules>
|
||||
<module>01-SimpleChat</module>
|
||||
<module>02-PersonaChat</module>
|
||||
<module>03-SimpleRag</module>
|
||||
<module>04-DynamicRag</module>
|
||||
<module>05-MultiModal</module>
|
||||
<module>06-Assistants</module>
|
||||
<!-- <module>04-DynamicRag</module> -->
|
||||
<!-- <module>05-MultiModal</module> -->
|
||||
<!-- <module>06-Assistants</module> -->
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-core</artifactId>
|
||||
<artifactId>semantickernel-bom</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>aiservices-azureopenai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>aiservices-huggingface</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>aiservices-ollama</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>aiservices-openai</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-plugin-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-planners</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.azure</groupId>
|
||||
<artifactId>azure-ai-openai</artifactId>
|
||||
<version>1.0.0-beta.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.15.2</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>aiservices-azureopenai</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>semantickernel-plugin-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.microsoft.semantic-kernel</groupId>
|
||||
<artifactId>aiservices-openai</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.azure</groupId>
|
||||
<artifactId>azure-ai-openai</artifactId>
|
||||
<version>1.0.0-beta.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>5.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>5.10.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<scope>test</scope>
|
||||
<version>5.10.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.wiremock</groupId>
|
||||
<artifactId>wiremock</artifactId>
|
||||
<version>3.3.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.24.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>2.0.9</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>run-sample</id>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<mainClass>Main</mainClass>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.jknack</groupId>
|
||||
<artifactId>handlebars</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.projectreactor</groupId>
|
||||
<artifactId>reactor-core</artifactId>
|
||||
@@ -41,5 +45,9 @@
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>jsr305</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user