diff --git a/.licenserc.yaml b/.licenserc.yaml index b5a6f7b8c..f436ea475 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -26,6 +26,7 @@ header: - '**/target/**' - '**/*.ftl' - '**/*.log' + - '**/*.st' - '.git/' - '.github/**' - '**/.gitignore' diff --git a/bigtop-manager-ai/bigtop-manager-ai-assistant/pom.xml b/bigtop-manager-ai/bigtop-manager-ai-assistant/pom.xml new file mode 100644 index 000000000..6f1fea818 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-assistant/pom.xml @@ -0,0 +1,44 @@ + + + + 4.0.0 + + org.apache.bigtop + bigtop-manager-ai + ${revision} + ../pom.xml + + + bigtop-manager-ai-assistant + ${project.artifactId} + Bigtop Manager AI Assistant + + + + org.apache.bigtop + bigtop-manager-ai-openai + + + org.apache.bigtop + bigtop-manager-ai-core + + + + diff --git a/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/java/org/apache/bigtop/manager/ai/assistant/GeneralAssistantFactory.java b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/java/org/apache/bigtop/manager/ai/assistant/GeneralAssistantFactory.java new file mode 100644 index 000000000..279567837 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/java/org/apache/bigtop/manager/ai/assistant/GeneralAssistantFactory.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.assistant; + +import org.apache.bigtop.manager.ai.assistant.provider.LocSystemPromptProvider; +import org.apache.bigtop.manager.ai.core.AbstractAIAssistantFactory; +import org.apache.bigtop.manager.ai.core.enums.PlatformType; +import org.apache.bigtop.manager.ai.core.factory.AIAssistant; +import org.apache.bigtop.manager.ai.core.factory.ToolBox; +import org.apache.bigtop.manager.ai.core.provider.AIAssistantConfigProvider; +import org.apache.bigtop.manager.ai.core.provider.SystemPromptProvider; +import org.apache.bigtop.manager.ai.openai.OpenAIAssistant; + +import dev.langchain4j.data.message.SystemMessage; +import dev.langchain4j.store.memory.chat.ChatMemoryStore; +import dev.langchain4j.store.memory.chat.InMemoryChatMemoryStore; + +import java.util.Objects; + +public class GeneralAssistantFactory extends AbstractAIAssistantFactory { + + private SystemPromptProvider systemPromptProvider = new LocSystemPromptProvider(); + private ChatMemoryStore chatMemoryStore = new InMemoryChatMemoryStore(); + + public GeneralAssistantFactory() {} + + public GeneralAssistantFactory(SystemPromptProvider systemPromptProvider) { + this.systemPromptProvider = systemPromptProvider; + } + + public GeneralAssistantFactory(SystemPromptProvider systemPromptProvider, ChatMemoryStore chatMemoryStore) { + this.systemPromptProvider = systemPromptProvider; + this.chatMemoryStore = chatMemoryStore; + } + + @Override + public AIAssistant createWithPrompt( + PlatformType platformType, AIAssistantConfigProvider assistantConfig, Object id, Object promptId) { + AIAssistant aiAssistant = create(platformType, assistantConfig, id); + SystemMessage systemPrompt = systemPromptProvider.getSystemPrompt(promptId); + aiAssistant.setSystemPrompt(systemPrompt); + return aiAssistant; + } + + @Override + public AIAssistant create(PlatformType platformType, AIAssistantConfigProvider assistantConfig, Object id) { + if (Objects.requireNonNull(platformType) == PlatformType.OPENAI) { + AIAssistant aiAssistant = OpenAIAssistant.builder() + .id(id) + .memoryStore(chatMemoryStore) + .withConfigProvider(assistantConfig) + .build(); + aiAssistant.setSystemPrompt(systemPromptProvider.getSystemPrompt()); + return aiAssistant; + } + return null; + } + + @Override + public ToolBox createToolBox(PlatformType platformType) { + return null; + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/AIAssistantConfig.java b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/AIAssistantConfig.java new file mode 100644 index 000000000..f632f8392 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/AIAssistantConfig.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.assistant.provider; + +import org.apache.bigtop.manager.ai.core.provider.AIAssistantConfigProvider; + +import java.util.HashMap; +import java.util.Map; + +public class AIAssistantConfig implements AIAssistantConfigProvider { + private final Map configMap; + + private AIAssistantConfig(Map configMap) { + this.configMap = configMap; + } + + public static Builder builder() { + return new Builder(); + } + + public static Builder withDefault(String baseUrl, String apiKey) { + Builder builder = new Builder(); + return builder.set("baseUrl", baseUrl).set("apiKey", apiKey); + } + + @Override + public Map configs() { + + return configMap; + } + + public static class Builder { + private final Map configs; + + public Builder() { + configs = new HashMap<>(); + configs.put("memoryLen", "30"); + } + + public Builder set(String key, String value) { + configs.put(key, value); + return this; + } + + public AIAssistantConfig build() { + return new AIAssistantConfig(configs); + } + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/LocSystemPromptProvider.java b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/LocSystemPromptProvider.java new file mode 100644 index 000000000..1603601a1 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/java/org/apache/bigtop/manager/ai/assistant/provider/LocSystemPromptProvider.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.assistant.provider; + +import org.apache.bigtop.manager.ai.core.provider.SystemPromptProvider; + +import org.springframework.util.ResourceUtils; + +import dev.langchain4j.data.message.SystemMessage; +import lombok.extern.slf4j.Slf4j; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Objects; + +@Slf4j +public class LocSystemPromptProvider implements SystemPromptProvider { + + public static final String DEFAULT = "default"; + private static final String SYSTEM_PROMPT_PATH = "src/main/resources/"; + private static final String DEFAULT_NAME = "big-data-professor.st"; + + @Override + public SystemMessage getSystemPrompt(Object id) { + if (Objects.equals(id.toString(), DEFAULT)) { + return getSystemPrompt(); + } else { + return loadPromptFromFile(id.toString()); + } + } + + @Override + public SystemMessage getSystemPrompt() { + return loadPromptFromFile(DEFAULT_NAME); + } + + private SystemMessage loadPromptFromFile(String fileName) { + final String filePath = SYSTEM_PROMPT_PATH + fileName; + try { + File file = ResourceUtils.getFile(filePath); + String text = Files.readString(file.toPath(), StandardCharsets.UTF_8); + return SystemMessage.from(text); + } catch (IOException e) { + // + log.error( + "Exception occurred while loading SystemPrompt from local. Here is some information:{}", + e.getMessage()); + return SystemMessage.from(""); + } + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/resources/big-data-professor.st b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/resources/big-data-professor.st new file mode 100644 index 000000000..446f31431 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/main/resources/big-data-professor.st @@ -0,0 +1 @@ +You are a qualified big data expert who knows the world's leading open source big data component engineering projects. Now please focus on the content in the direction of big data. I will ask you some questions and hope to get your answers. \ No newline at end of file diff --git a/bigtop-manager-ai/bigtop-manager-ai-assistant/src/test/java/org/apache/bigtop/manager/ai/assistant/AIAssistantServiceTest.java b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/test/java/org/apache/bigtop/manager/ai/assistant/AIAssistantServiceTest.java new file mode 100644 index 000000000..40c21d58d --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/test/java/org/apache/bigtop/manager/ai/assistant/AIAssistantServiceTest.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.assistant; + +import org.apache.bigtop.manager.ai.assistant.provider.AIAssistantConfig; +import org.apache.bigtop.manager.ai.core.enums.PlatformType; +import org.apache.bigtop.manager.ai.core.factory.AIAssistant; +import org.apache.bigtop.manager.ai.core.factory.AIAssistantFactory; +import org.apache.bigtop.manager.ai.core.provider.AIAssistantConfigProvider; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import dev.langchain4j.model.openai.OpenAiChatModelName; +import reactor.core.publisher.Flux; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.mockito.Mockito.when; + +public class AIAssistantServiceTest { + + private AIAssistantConfigProvider configProvider = AIAssistantConfig.builder() + .set("apiKey", "sk-") + // The `baseUrl` has a default value that is automatically generated based on the `PlatformType`. + .set("baseUrl", "https://api.openai.com/v1") + // default 30 + .set("memoryLen", "10") + .set("modelName", OpenAiChatModelName.GPT_3_5_TURBO.toString()) + .build(); + + @Mock + private AIAssistant aiAssistant; + + @Mock + private AIAssistantFactory aiAssistantFactory; + + @BeforeEach + public void init() { + MockitoAnnotations.openMocks(this); + when(aiAssistant.ask("1?")).thenReturn("1"); + when(aiAssistant.streamAsk("stream 1?")).thenReturn(Flux.create(emmit -> { + final String text = "stream text"; + for (int i = 0; i < text.length(); i++) { + emmit.next(text.charAt(i) + ""); + } + })); + when(aiAssistantFactory.create(PlatformType.OPENAI, configProvider)).thenReturn(this.aiAssistant); + when(aiAssistant.getPlatform()).thenReturn(PlatformType.OPENAI.getValue()); + } + + @Test + public void createNew2SimpleChat() { + AIAssistant aiAssistant = aiAssistantFactory.create(PlatformType.OPENAI, configProvider); + String ask = aiAssistant.ask("1?"); + assertFalse(ask.isEmpty()); + System.out.println(ask); + } + + @Test + public void createNew2StreamChat() throws InterruptedException { + AIAssistant aiAssistant = aiAssistantFactory.create(PlatformType.OPENAI, configProvider); + Flux stringFlux = aiAssistant.streamAsk("stream 1?"); + stringFlux.subscribe( + System.out::println, + error -> System.out.println("error:" + error), + () -> System.out.println("Completed")); + Thread.sleep(1000); + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-assistant/src/test/java/org/apache/bigtop/manager/ai/assistant/SystemPromptProviderTests.java b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/test/java/org/apache/bigtop/manager/ai/assistant/SystemPromptProviderTests.java new file mode 100644 index 000000000..db9be1ae0 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-assistant/src/test/java/org/apache/bigtop/manager/ai/assistant/SystemPromptProviderTests.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.assistant; + +import org.apache.bigtop.manager.ai.assistant.provider.LocSystemPromptProvider; +import org.apache.bigtop.manager.ai.core.provider.SystemPromptProvider; + +import org.junit.jupiter.api.Test; + +import dev.langchain4j.data.message.SystemMessage; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +public class SystemPromptProviderTests { + + private SystemPromptProvider systemPromptProvider = new LocSystemPromptProvider(); + + @Test + public void loadSystemPromptTest() { + System.out.println(systemPromptProvider.getSystemPrompt()); + } + + @Test + public void loadSystemPromptByIdTest() { + SystemMessage systemPrompt1 = systemPromptProvider.getSystemPrompt("big-data-professor.st"); + assertFalse(systemPrompt1.text().isEmpty()); + System.out.println(systemPrompt1.text()); + + SystemMessage systemPrompt2 = systemPromptProvider.getSystemPrompt(LocSystemPromptProvider.DEFAULT); + assertFalse(systemPrompt2.text().isEmpty()); + System.out.println(systemPrompt2.text()); + + assertEquals(systemPrompt1.text(), systemPrompt2.text()); + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/pom.xml b/bigtop-manager-ai/bigtop-manager-ai-core/pom.xml new file mode 100644 index 000000000..5f9de5f7e --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/pom.xml @@ -0,0 +1,32 @@ + + + + 4.0.0 + + org.apache.bigtop + bigtop-manager-ai + ${revision} + + + bigtop-manager-ai-core + ${project.artifactId} + Bigtop Manager AI Core + + diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistant.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistant.java new file mode 100644 index 000000000..e5087e303 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistant.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core; + +import org.apache.bigtop.manager.ai.core.factory.AIAssistant; + +import dev.langchain4j.data.message.AiMessage; +import dev.langchain4j.data.message.ChatMessage; +import dev.langchain4j.data.message.SystemMessage; +import dev.langchain4j.memory.ChatMemory; +import dev.langchain4j.model.StreamingResponseHandler; +import dev.langchain4j.model.chat.ChatLanguageModel; +import dev.langchain4j.model.chat.StreamingChatLanguageModel; +import dev.langchain4j.model.output.Response; +import reactor.core.publisher.Flux; +import reactor.core.publisher.FluxSink; + +public abstract class AbstractAIAssistant implements AIAssistant { + private final ChatLanguageModel chatLanguageModel; + private final StreamingChatLanguageModel streamingChatLanguageModel; + private final Object assistantId; + private final ChatMemory chatMemory; + + public AbstractAIAssistant( + ChatLanguageModel chatLanguageModel, + StreamingChatLanguageModel streamingChatLanguageModel, + ChatMemory chatMemory) { + this.chatLanguageModel = chatLanguageModel; + this.streamingChatLanguageModel = streamingChatLanguageModel; + this.chatMemory = chatMemory; + this.assistantId = this.chatMemory.id(); + } + + @Override + public Flux streamAsk(ChatMessage chatMessage) { + chatMemory.add(chatMessage); + Flux streamAiMessage = Flux.create( + emitter -> { + streamingChatLanguageModel.generate(chatMemory.messages(), new StreamingResponseHandler<>() { + @Override + public void onNext(String token) { + emitter.next(token); + } + + @Override + public void onError(Throwable error) { + emitter.error(error); + } + + @Override + public void onComplete(Response response) { + StreamingResponseHandler.super.onComplete(response); + chatMemory.add(response.content()); + } + }); + }, + FluxSink.OverflowStrategy.BUFFER); + + return streamAiMessage; + } + + @Override + public String ask(ChatMessage chatMessage) { + chatMemory.add(chatMessage); + Response generate = chatLanguageModel.generate(chatMemory.messages()); + String aiMessage = generate.content().text(); + chatMemory.add(AiMessage.from(aiMessage)); + return aiMessage; + } + + @Override + public void setSystemPrompt(SystemMessage systemPrompt) { + chatMemory.add(systemPrompt); + } + + @Override + public Object getId() { + return chatMemory.id(); + } + + @Override + public void resetMemory() { + chatMemory.clear(); + } + + @Override + public ChatMemory getMemory() { + return this.chatMemory; + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistantFactory.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistantFactory.java new file mode 100644 index 000000000..4a878e9c0 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/AbstractAIAssistantFactory.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core; + +import org.apache.bigtop.manager.ai.core.factory.AIAssistantFactory; + +public abstract class AbstractAIAssistantFactory implements AIAssistantFactory {} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/enums/PlatformType.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/enums/PlatformType.java new file mode 100644 index 000000000..0f5cb6082 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/enums/PlatformType.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core.enums; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +public enum PlatformType { + OPENAI("openai"); + + private final String value; + + PlatformType(String value) { + this.value = value; + } + + public static List getPlatforms() { + return Arrays.stream(values()).map(item -> item.value).collect(Collectors.toList()); + } + + public static PlatformType getPlatformType(String value) { + if (Objects.isNull(value) || value.isEmpty()) { + return null; + } + for (PlatformType platformType : PlatformType.values()) { + if (platformType.value.equals(value)) { + return platformType; + } + } + return null; + } + + public String getValue() { + return this.value; + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/exception/AssistantConfigNotSetException.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/exception/AssistantConfigNotSetException.java new file mode 100644 index 000000000..37e634b82 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/exception/AssistantConfigNotSetException.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core.exception; + +public class AssistantConfigNotSetException extends RuntimeException { + private String paramName; + + public AssistantConfigNotSetException(String paramName) { + super(paramName + " is a required parameter. You need to set."); + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/exception/PlatformNotFoundException.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/exception/PlatformNotFoundException.java new file mode 100644 index 000000000..290d179b4 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/exception/PlatformNotFoundException.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core.exception; + +public class PlatformNotFoundException extends RuntimeException { + public PlatformNotFoundException(String platform) { + super(platform + " platform not found. Please select one from PlatformType."); + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistant.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistant.java new file mode 100644 index 000000000..8f4ef8e2e --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistant.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core.factory; + +import dev.langchain4j.data.message.ChatMessage; +import dev.langchain4j.data.message.SystemMessage; +import dev.langchain4j.data.message.UserMessage; +import dev.langchain4j.memory.ChatMemory; +import reactor.core.publisher.Flux; + +public interface AIAssistant { + + /** + * This ID is the unique identifier for the {@link AIAssistant}. + * Its memory storage is independent of AIAssistant instances in other threads. + * @return + */ + Object getId(); + + /** + * This is a conversation based on streaming output. + * @param userMessage + * @return + */ + Flux streamAsk(ChatMessage userMessage); + + /** + * This is a conversation based on blocking output. + * @param userMessage + * @return + */ + String ask(ChatMessage userMessage); + + /** + * This is primarily used to retrieve the AI assistant's history of chat conversations. + * @return + */ + ChatMemory getMemory(); + + /** + * This is used to get the AIAssistant's Platform + * @return + */ + String getPlatform(); + + void setSystemPrompt(SystemMessage systemPrompt); + + void resetMemory(); + + default Flux streamAsk(String message) { + return streamAsk(UserMessage.from(message)); + } + + default String ask(String message) { + return ask(UserMessage.from(message)); + } + + default void setSystemPrompt(String systemPrompt) { + setSystemPrompt(SystemMessage.systemMessage(systemPrompt)); + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistantFactory.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistantFactory.java new file mode 100644 index 000000000..6610f9c4b --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/factory/AIAssistantFactory.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core.factory; + +import org.apache.bigtop.manager.ai.core.enums.PlatformType; +import org.apache.bigtop.manager.ai.core.exception.PlatformNotFoundException; +import org.apache.bigtop.manager.ai.core.provider.AIAssistantConfigProvider; + +import java.util.Objects; +import java.util.UUID; + +public interface AIAssistantFactory { + + AIAssistant createWithPrompt( + PlatformType platformType, AIAssistantConfigProvider assistantConfig, Object id, Object promptId); + + AIAssistant create(PlatformType platformType, AIAssistantConfigProvider assistantConfig, Object id); + + ToolBox createToolBox(PlatformType platformType); + + default AIAssistant createWithPrompt( + PlatformType platformType, AIAssistantConfigProvider assistantConfig, Object prompt) { + return createWithPrompt(platformType, assistantConfig, UUID.randomUUID().toString(), prompt); + } + + default AIAssistant create(String platform, AIAssistantConfigProvider assistantConfigProvider, Object id) { + PlatformType platformType = PlatformType.getPlatformType(platform); + if (Objects.isNull(platformType)) { + throw new PlatformNotFoundException(platform); + } + return create(platformType, assistantConfigProvider, id); + } + + default AIAssistant create(PlatformType platformType, AIAssistantConfigProvider assistantConfigProvider) { + return create(platformType, assistantConfigProvider, UUID.randomUUID().toString()); + } + + default AIAssistant create(String platform, AIAssistantConfigProvider assistantConfig) { + PlatformType platformType = PlatformType.getPlatformType(platform); + if (Objects.isNull(platformType)) { + throw new PlatformNotFoundException(platform); + } + return create(platformType, assistantConfig); + } + + default ToolBox createToolBox(String platform) { + PlatformType platformType = PlatformType.getPlatformType(platform); + if (Objects.isNull(platformType)) { + throw new PlatformNotFoundException(platform); + } + return createToolBox(platformType); + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/factory/ToolBox.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/factory/ToolBox.java new file mode 100644 index 000000000..47ee00444 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/factory/ToolBox.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core.factory; + +import reactor.core.publisher.Flux; + +import java.util.List; + +public interface ToolBox { + + List getTools(); + + String invoke(String toolName); + + Flux streamInvoke(String toolName); +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/provider/AIAssistantConfigProvider.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/provider/AIAssistantConfigProvider.java new file mode 100644 index 000000000..ea05b98ed --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/provider/AIAssistantConfigProvider.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core.provider; + +import java.util.Map; + +public interface AIAssistantConfigProvider { + Map configs(); +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/provider/SystemPromptProvider.java b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/provider/SystemPromptProvider.java new file mode 100644 index 000000000..5d6865fbd --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-core/src/main/java/org/apache/bigtop/manager/ai/core/provider/SystemPromptProvider.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.core.provider; + +import dev.langchain4j.data.message.SystemMessage; + +public interface SystemPromptProvider { + + // Return the SystemPrompt for the specified ID. + SystemMessage getSystemPrompt(Object id); + + // return default system prompt + SystemMessage getSystemPrompt(); +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-openai/pom.xml b/bigtop-manager-ai/bigtop-manager-ai-openai/pom.xml new file mode 100644 index 000000000..c918364a9 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-openai/pom.xml @@ -0,0 +1,44 @@ + + + + 4.0.0 + + org.apache.bigtop + bigtop-manager-ai + ${revision} + + + bigtop-manager-ai-openai + ${project.artifactId} + Bigtop Manager AI OpenAI + + + + org.apache.bigtop + bigtop-manager-ai-core + ${revision} + + + + dev.langchain4j + langchain4j-open-ai + + + diff --git a/bigtop-manager-ai/bigtop-manager-ai-openai/src/main/java/org/apache/bigtop/manager/ai/openai/OpenAIAssistant.java b/bigtop-manager-ai/bigtop-manager-ai-openai/src/main/java/org/apache/bigtop/manager/ai/openai/OpenAIAssistant.java new file mode 100644 index 000000000..1d76b6254 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-openai/src/main/java/org/apache/bigtop/manager/ai/openai/OpenAIAssistant.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.openai; + +import org.apache.bigtop.manager.ai.core.AbstractAIAssistant; +import org.apache.bigtop.manager.ai.core.factory.AIAssistant; +import org.apache.bigtop.manager.ai.core.provider.AIAssistantConfigProvider; + +import org.springframework.util.NumberUtils; + +import dev.langchain4j.internal.ValidationUtils; +import dev.langchain4j.memory.ChatMemory; +import dev.langchain4j.memory.chat.MessageWindowChatMemory; +import dev.langchain4j.model.chat.ChatLanguageModel; +import dev.langchain4j.model.chat.StreamingChatLanguageModel; +import dev.langchain4j.model.openai.OpenAiChatModel; +import dev.langchain4j.model.openai.OpenAiStreamingChatModel; +import dev.langchain4j.store.memory.chat.ChatMemoryStore; + +import java.util.HashMap; +import java.util.Map; + +public class OpenAIAssistant extends AbstractAIAssistant { + + private static final String PLATFORM_NAME = "openai"; + private static final String BASE_URL = "https://api.openai.com/v1"; + private static final String MODEL_NAME = "gpt-3.5-turbo"; + + private OpenAIAssistant( + ChatLanguageModel chatLanguageModel, + StreamingChatLanguageModel streamingChatLanguageModel, + ChatMemory chatMemory) { + super(chatLanguageModel, streamingChatLanguageModel, chatMemory); + } + + @Override + public String getPlatform() { + return PLATFORM_NAME; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private Object id; + + private Map configs = new HashMap<>(); + private ChatMemoryStore chatMemoryStore; + + public Builder() { + configs.put("baseUrl", BASE_URL); + configs.put("modelName", MODEL_NAME); + } + + public Builder withConfigProvider(AIAssistantConfigProvider configProvider) { + this.configs = configProvider.configs(); + return this; + } + + public Builder id(Object id) { + this.id = id; + return this; + } + + public Builder memoryStore(ChatMemoryStore chatMemoryStore) { + this.chatMemoryStore = chatMemoryStore; + return this; + } + + public AIAssistant build() { + ValidationUtils.ensureNotNull(id, "id"); + String baseUrl = configs.get("baseUrl"); + String modelName = configs.get("modelName"); + String apiKey = ValidationUtils.ensureNotNull(configs.get("apiKey"), "apiKey"); + Integer memoryLen = ValidationUtils.ensureNotNull( + NumberUtils.parseNumber(configs.get("memoryLen"), Integer.class), "memoryLen not a number."); + ChatLanguageModel openAiChatModel = OpenAiChatModel.builder() + .apiKey(apiKey) + .baseUrl(baseUrl) + .modelName(modelName) + .build(); + StreamingChatLanguageModel openaiStreamChatModel = OpenAiStreamingChatModel.builder() + .apiKey(apiKey) + .baseUrl(baseUrl) + .modelName(modelName) + .build(); + MessageWindowChatMemory chatMemory = MessageWindowChatMemory.builder() + .id(id) + .chatMemoryStore(chatMemoryStore) + .maxMessages(memoryLen) + .build(); + return new OpenAIAssistant(openAiChatModel, openaiStreamChatModel, chatMemory); + } + } +} diff --git a/bigtop-manager-ai/bigtop-manager-ai-openai/src/main/java/org/apache/bigtop/manager/ai/openai/OpenAIToolBox.java b/bigtop-manager-ai/bigtop-manager-ai-openai/src/main/java/org/apache/bigtop/manager/ai/openai/OpenAIToolBox.java new file mode 100644 index 000000000..26b7a5492 --- /dev/null +++ b/bigtop-manager-ai/bigtop-manager-ai-openai/src/main/java/org/apache/bigtop/manager/ai/openai/OpenAIToolBox.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bigtop.manager.ai.openai; + +import org.apache.bigtop.manager.ai.core.factory.ToolBox; + +import reactor.core.publisher.Flux; + +import java.util.List; + +public class OpenAIToolBox implements ToolBox { + @Override + public List getTools() { + return null; + } + + @Override + public String invoke(String toolName) { + return null; + } + + @Override + public Flux streamInvoke(String toolName) { + return null; + } +} diff --git a/bigtop-manager-ai/pom.xml b/bigtop-manager-ai/pom.xml new file mode 100644 index 000000000..58a969811 --- /dev/null +++ b/bigtop-manager-ai/pom.xml @@ -0,0 +1,70 @@ + + + + 4.0.0 + + org.apache.bigtop + bigtop-manager + ${revision} + ../pom.xml + + + bigtop-manager-ai + pom + ${project.artifactId} + Bigtop Manager AI + + bigtop-manager-ai-openai + bigtop-manager-ai-core + bigtop-manager-ai-assistant + + + + + + org.apache.bigtop + bigtop-manager-bom + ${project.version} + pom + import + + + + + + + dev.langchain4j + langchain4j + + + org.springframework.boot + spring-boot-starter-webflux + + + org.projectlombok + lombok + + + org.apache.commons + commons-lang3 + + + + diff --git a/bigtop-manager-bom/pom.xml b/bigtop-manager-bom/pom.xml index abd15d6eb..d0a4ad40d 100644 --- a/bigtop-manager-bom/pom.xml +++ b/bigtop-manager-bom/pom.xml @@ -49,6 +49,7 @@ 6.4.11 1.12.4 8.1.2.192 + 0.33.0 @@ -236,6 +237,16 @@ grpc-client-spring-boot-starter ${grpc-spring-boot.version} + + dev.langchain4j + langchain4j + ${langchain4j.version} + + + dev.langchain4j + langchain4j-open-ai + ${langchain4j.version} + diff --git a/pom.xml b/pom.xml index 173c2efd8..aa47ff3ab 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,7 @@ bigtop-manager-ui bigtop-manager-dao bigtop-manager-grpc + bigtop-manager-ai @@ -116,6 +117,30 @@ bigtop-manager-ui ${project.version} + + + org.apache.bigtop + bigtop-manager-ai + ${project.version} + + + + org.apache.bigtop + bigtop-manager-ai-core + ${project.version} + + + + org.apache.bigtop + bigtop-manager-ai-openai + ${project.version} + + + + org.apache.bigtop + bigtop-manager-ai-assistant + ${project.version} +