From 46d2d03b7329ae245ad116a7544460bf6b1c44e4 Mon Sep 17 00:00:00 2001
From: Arpit Gupta <162559421+arpitg-1@users.noreply.github.com>
Date: Wed, 7 Aug 2024 15:50:48 +0530
Subject: [PATCH] [WIP] W-16354625: Added required exceptions for each
operation (#18)
* W-16354625: Added required exceptions for each operation
* W-16354625: Added exception handling for tools operations
* W-16354625: Fixed reformatting
* W-16354625: Bug fixes and added supported errors per operation
---
pom.xml | 2 +-
.../config/LangchainLLMConfiguration.java | 5 +-
.../internal/error/MuleChainErrorType.java | 5 +-
.../provider/AiServiceErrorTypeProvider.java | 23 +
.../provider/EmbeddingErrorTypeProvider.java | 28 +
.../provider/ImageErrorTypeProvider.java | 27 +
.../internal/exception/ChatException.java | 14 +
.../exception/FileHandlingException.java | 18 +
.../exception/PromptTemplateException.java | 14 +
.../exception/SentimentAnalyzerException.java | 14 +
.../config/ConfigValidationException.java | 14 +
.../EmbeddingStoreOperationsException.java | 14 +
.../exception/embedding/RagException.java | 14 +
.../image/ImageAnalyzerException.java | 14 +
.../image/ImageGenerationException.java | 14 +
.../image/ImageProcessingException.java | 14 +
.../tools/ToolsOperationException.java | 14 +
.../LangchainEmbeddingStoresOperations.java | 681 ++++++++++--------
.../LangchainImageModelsOperations.java | 92 ++-
.../operation/LangchainLLMOperations.java | 86 ++-
20 files changed, 726 insertions(+), 381 deletions(-)
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/error/provider/AiServiceErrorTypeProvider.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/error/provider/EmbeddingErrorTypeProvider.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/error/provider/ImageErrorTypeProvider.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/ChatException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/FileHandlingException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/PromptTemplateException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/SentimentAnalyzerException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/config/ConfigValidationException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/embedding/EmbeddingStoreOperationsException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/embedding/RagException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageAnalyzerException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageGenerationException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageProcessingException.java
create mode 100644 src/main/java/org/mule/extension/mulechain/internal/exception/tools/ToolsOperationException.java
diff --git a/pom.xml b/pom.xml
index 3ad1aec..0f7bf82 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0
com.mule.mulechain
mulechain-ai-connector
- 0.2.13
+ 0.2.14-SNAPSHOT
mule-extension
MuleChain
diff --git a/src/main/java/org/mule/extension/mulechain/internal/config/LangchainLLMConfiguration.java b/src/main/java/org/mule/extension/mulechain/internal/config/LangchainLLMConfiguration.java
index b869a0c..2ad6d7c 100644
--- a/src/main/java/org/mule/extension/mulechain/internal/config/LangchainLLMConfiguration.java
+++ b/src/main/java/org/mule/extension/mulechain/internal/config/LangchainLLMConfiguration.java
@@ -4,6 +4,7 @@
package org.mule.extension.mulechain.internal.config;
import dev.langchain4j.model.chat.ChatLanguageModel;
+import org.mule.extension.mulechain.internal.exception.config.ConfigValidationException;
import org.mule.extension.mulechain.internal.operation.LangchainEmbeddingStoresOperations;
import org.mule.extension.mulechain.internal.operation.LangchainImageModelsOperations;
import org.mule.extension.mulechain.internal.llm.type.LangchainLLMType;
@@ -141,7 +142,7 @@ private ChatLanguageModel createModel(ConfigExtractor configExtractor) {
if (llmMap.containsKey(type)) {
return llmMap.get(type).apply(configExtractor, this);
}
- throw new IllegalArgumentException("LLM Type not supported: " + llmType);
+ throw new ConfigValidationException("LLM Type not supported: " + llmType);
}
@Override
@@ -151,7 +152,7 @@ public void initialise() throws InitialisationException {
configExtractor = configExtractorMap.get(config).apply(this);
model = createModel(configExtractor);
} else {
- throw new IllegalArgumentException("Config Type not supported: " + configType);
+ throw new ConfigValidationException("Config Type not supported: " + configType);
}
}
}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/error/MuleChainErrorType.java b/src/main/java/org/mule/extension/mulechain/internal/error/MuleChainErrorType.java
index cf68ef6..716f206 100644
--- a/src/main/java/org/mule/extension/mulechain/internal/error/MuleChainErrorType.java
+++ b/src/main/java/org/mule/extension/mulechain/internal/error/MuleChainErrorType.java
@@ -1,8 +1,11 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
package org.mule.extension.mulechain.internal.error;
import org.mule.runtime.extension.api.error.ErrorTypeDefinition;
public enum MuleChainErrorType implements ErrorTypeDefinition {
- INVALID_AUTHENTICATION, IO_EXCEPTION, TIME_OUT, RATE_LIMIT_OR_QUOTA_EXCEEDED;
+ AI_SERVICES_FAILURE, IMAGE_ANALYSIS_FAILURE, IMAGE_GENERATION_FAILURE, IMAGE_PROCESSING_FAILURE, FILE_HANDLING_FAILURE, RAG_FAILURE, EMBEDDING_OPERATIONS_FAILURE, TOOLS_OPERATION_FAILURE, VALIDATION_FAILURE
}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/error/provider/AiServiceErrorTypeProvider.java b/src/main/java/org/mule/extension/mulechain/internal/error/provider/AiServiceErrorTypeProvider.java
new file mode 100644
index 0000000..6486822
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/error/provider/AiServiceErrorTypeProvider.java
@@ -0,0 +1,23 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.error.provider;
+
+import org.mule.runtime.extension.api.annotation.error.ErrorTypeProvider;
+import org.mule.runtime.extension.api.error.ErrorTypeDefinition;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.util.Collections.unmodifiableSet;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.AI_SERVICES_FAILURE;
+
+public class AiServiceErrorTypeProvider implements ErrorTypeProvider {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Set getErrorTypes() {
+ return unmodifiableSet(new HashSet<>(Collections.singletonList(AI_SERVICES_FAILURE)));
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/error/provider/EmbeddingErrorTypeProvider.java b/src/main/java/org/mule/extension/mulechain/internal/error/provider/EmbeddingErrorTypeProvider.java
new file mode 100644
index 0000000..c184588
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/error/provider/EmbeddingErrorTypeProvider.java
@@ -0,0 +1,28 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.error.provider;
+
+import org.mule.runtime.extension.api.annotation.error.ErrorTypeProvider;
+import org.mule.runtime.extension.api.error.ErrorTypeDefinition;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableSet;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.AI_SERVICES_FAILURE;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.EMBEDDING_OPERATIONS_FAILURE;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.FILE_HANDLING_FAILURE;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.RAG_FAILURE;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.TOOLS_OPERATION_FAILURE;
+
+public class EmbeddingErrorTypeProvider implements ErrorTypeProvider {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Set getErrorTypes() {
+ return unmodifiableSet(new HashSet<>(asList(EMBEDDING_OPERATIONS_FAILURE, AI_SERVICES_FAILURE, RAG_FAILURE,
+ FILE_HANDLING_FAILURE, TOOLS_OPERATION_FAILURE)));
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/error/provider/ImageErrorTypeProvider.java b/src/main/java/org/mule/extension/mulechain/internal/error/provider/ImageErrorTypeProvider.java
new file mode 100644
index 0000000..dbb58a3
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/error/provider/ImageErrorTypeProvider.java
@@ -0,0 +1,27 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.error.provider;
+
+import org.mule.runtime.extension.api.annotation.error.ErrorTypeProvider;
+import org.mule.runtime.extension.api.error.ErrorTypeDefinition;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableSet;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.FILE_HANDLING_FAILURE;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.IMAGE_ANALYSIS_FAILURE;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.IMAGE_GENERATION_FAILURE;
+import static org.mule.extension.mulechain.internal.error.MuleChainErrorType.IMAGE_PROCESSING_FAILURE;
+
+public class ImageErrorTypeProvider implements ErrorTypeProvider {
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Set getErrorTypes() {
+ return unmodifiableSet(new HashSet<>(asList(IMAGE_ANALYSIS_FAILURE, IMAGE_GENERATION_FAILURE, IMAGE_PROCESSING_FAILURE,
+ FILE_HANDLING_FAILURE)));
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/ChatException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/ChatException.java
new file mode 100644
index 0000000..b15a86c
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/ChatException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class ChatException extends ModuleException {
+
+ public ChatException(String message, Exception exception) {
+ super(message, MuleChainErrorType.AI_SERVICES_FAILURE, exception);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/FileHandlingException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/FileHandlingException.java
new file mode 100644
index 0000000..054ebf5
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/FileHandlingException.java
@@ -0,0 +1,18 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class FileHandlingException extends ModuleException {
+
+ public FileHandlingException(String message, Exception exception) {
+ super(message, MuleChainErrorType.FILE_HANDLING_FAILURE, exception);
+ }
+
+ public FileHandlingException(String message) {
+ super(message, MuleChainErrorType.FILE_HANDLING_FAILURE);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/PromptTemplateException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/PromptTemplateException.java
new file mode 100644
index 0000000..1d51edc
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/PromptTemplateException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class PromptTemplateException extends ModuleException {
+
+ public PromptTemplateException(String message, Exception exception) {
+ super(message, MuleChainErrorType.AI_SERVICES_FAILURE, exception);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/SentimentAnalyzerException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/SentimentAnalyzerException.java
new file mode 100644
index 0000000..6b59518
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/SentimentAnalyzerException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class SentimentAnalyzerException extends ModuleException {
+
+ public SentimentAnalyzerException(String message, Exception exception) {
+ super(message, MuleChainErrorType.AI_SERVICES_FAILURE, exception);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/config/ConfigValidationException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/config/ConfigValidationException.java
new file mode 100644
index 0000000..8d20fd3
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/config/ConfigValidationException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception.config;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class ConfigValidationException extends ModuleException {
+
+ public ConfigValidationException(String message) {
+ super(message, MuleChainErrorType.VALIDATION_FAILURE);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/embedding/EmbeddingStoreOperationsException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/embedding/EmbeddingStoreOperationsException.java
new file mode 100644
index 0000000..e583746
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/embedding/EmbeddingStoreOperationsException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception.embedding;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class EmbeddingStoreOperationsException extends ModuleException {
+
+ public EmbeddingStoreOperationsException(String message, Exception exception) {
+ super(message, MuleChainErrorType.EMBEDDING_OPERATIONS_FAILURE, exception);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/embedding/RagException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/embedding/RagException.java
new file mode 100644
index 0000000..748b57b
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/embedding/RagException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception.embedding;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class RagException extends ModuleException {
+
+ public RagException(String message, Exception exception) {
+ super(message, MuleChainErrorType.RAG_FAILURE, exception);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageAnalyzerException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageAnalyzerException.java
new file mode 100644
index 0000000..745b8fc
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageAnalyzerException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception.image;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class ImageAnalyzerException extends ModuleException {
+
+ public ImageAnalyzerException(String message, Exception exception) {
+ super(message, MuleChainErrorType.IMAGE_ANALYSIS_FAILURE, exception);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageGenerationException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageGenerationException.java
new file mode 100644
index 0000000..ab62051
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageGenerationException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception.image;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class ImageGenerationException extends ModuleException {
+
+ public ImageGenerationException(String message, Exception exception) {
+ super(message, MuleChainErrorType.IMAGE_GENERATION_FAILURE, exception);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageProcessingException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageProcessingException.java
new file mode 100644
index 0000000..f22c58f
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/image/ImageProcessingException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception.image;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class ImageProcessingException extends ModuleException {
+
+ public ImageProcessingException(String message, Exception exception) {
+ super(message, MuleChainErrorType.IMAGE_PROCESSING_FAILURE, exception);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/exception/tools/ToolsOperationException.java b/src/main/java/org/mule/extension/mulechain/internal/exception/tools/ToolsOperationException.java
new file mode 100644
index 0000000..5188ac7
--- /dev/null
+++ b/src/main/java/org/mule/extension/mulechain/internal/exception/tools/ToolsOperationException.java
@@ -0,0 +1,14 @@
+/**
+ * (c) 2003-2024 MuleSoft, Inc. The software in this package is published under the terms of the Commercial Free Software license V.1 a copy of which has been included with this distribution in the LICENSE.md file.
+ */
+package org.mule.extension.mulechain.internal.exception.tools;
+
+import org.mule.extension.mulechain.internal.error.MuleChainErrorType;
+import org.mule.runtime.extension.api.exception.ModuleException;
+
+public class ToolsOperationException extends ModuleException {
+
+ public ToolsOperationException(String message, Exception exception) {
+ super(message, MuleChainErrorType.TOOLS_OPERATION_FAILURE, exception);
+ }
+}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainEmbeddingStoresOperations.java b/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainEmbeddingStoresOperations.java
index 1cb0b31..77fb1d5 100644
--- a/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainEmbeddingStoresOperations.java
+++ b/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainEmbeddingStoresOperations.java
@@ -29,12 +29,19 @@
import org.mapdb.DB;
import org.mapdb.DBMaker;
import org.mule.extension.mulechain.internal.constants.MuleChainConstants;
+import org.mule.extension.mulechain.internal.error.provider.EmbeddingErrorTypeProvider;
+import org.mule.extension.mulechain.internal.exception.ChatException;
+import org.mule.extension.mulechain.internal.exception.embedding.EmbeddingStoreOperationsException;
+import org.mule.extension.mulechain.internal.exception.FileHandlingException;
+import org.mule.extension.mulechain.internal.exception.embedding.RagException;
+import org.mule.extension.mulechain.internal.exception.tools.ToolsOperationException;
import org.mule.extension.mulechain.internal.helpers.FileType;
import org.mule.extension.mulechain.internal.helpers.FileTypeParameters;
import org.mule.extension.mulechain.internal.config.LangchainLLMConfiguration;
import org.mule.extension.mulechain.internal.tools.GenericRestApiTool;
import org.mule.extension.mulechain.internal.util.JsonUtils;
import org.mule.runtime.extension.api.annotation.Alias;
+import org.mule.runtime.extension.api.annotation.error.Throws;
import org.mule.runtime.extension.api.annotation.param.MediaType;
import org.mule.runtime.extension.api.annotation.param.ParameterGroup;
import org.mule.runtime.extension.api.annotation.param.Config;
@@ -45,7 +52,6 @@
import dev.langchain4j.service.UserMessage;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
import dev.langchain4j.chain.ConversationalRetrievalChain;
@@ -72,6 +78,8 @@
import static dev.langchain4j.data.message.ChatMessageSerializer.messagesToJson;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+
+import org.mule.sdk.api.exception.ModuleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -82,7 +90,7 @@ public class LangchainEmbeddingStoresOperations {
private static final Logger LOGGER = LoggerFactory.getLogger(LangchainEmbeddingStoresOperations.class);
- private EmbeddingModel embeddingModel;
+ private final EmbeddingModel embeddingModel;
private static InMemoryEmbeddingStore deserializedStore;
@@ -100,45 +108,52 @@ public LangchainEmbeddingStoresOperations() {
@MediaType(value = ANY, strict = false)
@Alias("RAG-load-document")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String loadDocumentFile(@Config LangchainLLMConfiguration configuration, String data, String contextPath,
@ParameterGroup(name = "Context") FileTypeParameters fileType) {
- EmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>();
+ try {
+ EmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>();
- EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
- .documentSplitter(DocumentSplitters.recursive(1000, 200, new OpenAiTokenizer()))
- .embeddingModel(embeddingModel)
- .embeddingStore(embeddingStore)
- .build();
+ EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
+ .documentSplitter(DocumentSplitters.recursive(1000, 200, new OpenAiTokenizer()))
+ .embeddingModel(embeddingModel)
+ .embeddingStore(embeddingStore)
+ .build();
- LOGGER.info("RAG loading document with file type: {}", fileType.getFileType());
+ LOGGER.info("RAG loading document with file type: {}", fileType.getFileType());
- ingestDocument(fileType, contextPath, ingestor);
+ ingestDocument(fileType, contextPath, ingestor);
- ChatLanguageModel model = configuration.getModel();
+ ChatLanguageModel model = configuration.getModel();
- // MIGRATE CHAINS TO AI SERVICES: https://docs.langchain4j.dev/tutorials/ai-services/
- // and Specifically the RAG section: https://docs.langchain4j.dev/tutorials/ai-services#rag
- //chains are legacy now, please use AI Services: https://docs.langchain4j.dev/tutorials/ai-services > Update to AI Services
+ // MIGRATE CHAINS TO AI SERVICES: https://docs.langchain4j.dev/tutorials/ai-services/
+ // and Specifically the RAG section: https://docs.langchain4j.dev/tutorials/ai-services#rag
+ //chains are legacy now, please use AI Services: https://docs.langchain4j.dev/tutorials/ai-services > Update to AI Services
- ContentRetriever contentRetriever = new EmbeddingStoreContentRetriever(embeddingStore, embeddingModel);
+ ContentRetriever contentRetriever = new EmbeddingStoreContentRetriever(embeddingStore, embeddingModel);
- AssistantSources assistant = AiServices.builder(AssistantSources.class)
- .chatLanguageModel(model)
- .contentRetriever(contentRetriever)
- .build();
+ AssistantSources assistant = AiServices.builder(AssistantSources.class)
+ .chatLanguageModel(model)
+ .contentRetriever(contentRetriever)
+ .build();
- Result answer = assistant.chat(data);
+ Result answer = assistant.chat(data);
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, answer.content());
- jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(answer));
- jsonObject.put(MuleChainConstants.FILE_PATH, contextPath);
- jsonObject.put(MuleChainConstants.FILE_TYPE, fileType.getFileType());
- jsonObject.put(MuleChainConstants.QUESTION, data);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, answer.content());
+ jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(answer));
+ jsonObject.put(MuleChainConstants.FILE_PATH, contextPath);
+ jsonObject.put(MuleChainConstants.FILE_TYPE, fileType.getFileType());
+ jsonObject.put(MuleChainConstants.QUESTION, data);
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (ModuleException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new RagException("Error while loading and retrieving content from the document " + contextPath, e);
+ }
}
private void ingestDocument(FileTypeParameters fileType, String contextPath, EmbeddingStoreIngestor ingestor) {
@@ -157,7 +172,7 @@ private void ingestDocument(FileTypeParameters fileType, String contextPath, Emb
try {
url = new URL(contextPath);
} catch (MalformedURLException e) {
- LOGGER.error("Error while loading the document: " + contextPath, e);
+ throw new FileHandlingException("Error while loading the document: " + contextPath, e);
}
Document htmlDocument = UrlDocumentLoader.load(url, new TextDocumentParser());
@@ -167,7 +182,7 @@ private void ingestDocument(FileTypeParameters fileType, String contextPath, Emb
ingestor.ingest(document);
break;
default:
- throw new IllegalArgumentException("Unsupported File Type: " + fileType.getFileType());
+ throw new FileHandlingException("Unsupported File Type: " + fileType.getFileType());
}
}
@@ -183,42 +198,45 @@ interface AssistantMemory {
*/
@MediaType(value = ANY, strict = false)
@Alias("CHAT-answer-prompt-with-memory")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String chatWithPersistentMemory(@Config LangchainLLMConfiguration configuration, String data, String memoryName,
String dbFilePath, int maxMessages) {
- ChatLanguageModel model = configuration.getModel();
+ try {
+ ChatLanguageModel model = configuration.getModel();
- PersistentChatMemoryStore.initialize(dbFilePath);
+ PersistentChatMemoryStore.initialize(dbFilePath);
- PersistentChatMemoryStore store = new PersistentChatMemoryStore();
+ PersistentChatMemoryStore store = new PersistentChatMemoryStore();
- ChatMemoryProvider chatMemoryProvider = memoryId -> MessageWindowChatMemory.builder()
- .id(memoryName)
- .maxMessages(maxMessages)
- .chatMemoryStore(store)
- .build();
+ ChatMemoryProvider chatMemoryProvider = memoryId -> MessageWindowChatMemory.builder()
+ .id(memoryName)
+ .maxMessages(maxMessages)
+ .chatMemoryStore(store)
+ .build();
- AssistantMemory assistant = AiServices.builder(AssistantMemory.class)
- .chatLanguageModel(model)
- .chatMemoryProvider(chatMemoryProvider)
- .build();
+ AssistantMemory assistant = AiServices.builder(AssistantMemory.class)
+ .chatLanguageModel(model)
+ .chatMemoryProvider(chatMemoryProvider)
+ .build();
- Result response = assistant.chat(memoryName, data);
+ Result response = assistant.chat(memoryName, data);
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, response.content());
- jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(response));
- jsonObject.put(MuleChainConstants.MEMORY_NAME, memoryName);
- jsonObject.put(MuleChainConstants.DB_FILE_PATH, dbFilePath);
- jsonObject.put(MuleChainConstants.MAX_MESSAGES, maxMessages);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, response.content());
+ jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(response));
+ jsonObject.put(MuleChainConstants.MEMORY_NAME, memoryName);
+ jsonObject.put(MuleChainConstants.DB_FILE_PATH, dbFilePath);
+ jsonObject.put(MuleChainConstants.MAX_MESSAGES, maxMessages);
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new ChatException("Error while responding with the chat provided", e);
+ }
}
static class PersistentChatMemoryStore implements ChatMemoryStore {
- //private final DB db = DBMaker.fileDB("/Users/amir.khan/Documents/langchain4mule resources/multi-user-chat-memory.db").transactionEnable().fileLockDisable().make();
- //private final Map map = db.hashMap("messages", INTEGER, STRING).createOrOpen();
private static DB db;
// private static Map map;
private static Map map;
@@ -228,7 +246,6 @@ public static void initialize(String dbMFilePath) {
.transactionEnable()
.fileLockDisable()
.make();
- //map = db.hashMap("messages", INTEGER, STRING).createOrOpen();
map = db.hashMap("messages", STRING, STRING).createOrOpen();
}
@@ -258,59 +275,64 @@ public void deleteMessages(Object memoryId) {
*/
@MediaType(value = ANY, strict = false)
@Alias("TOOLS-use-ai-service-legacy")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String useTools(@Config LangchainLLMConfiguration configuration, String data, String toolConfig) {
- EmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>();
+ try {
+ EmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>();
- EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
- .documentSplitter(DocumentSplitters.recursive(30000, 200))
- .embeddingModel(embeddingModel)
- .embeddingStore(embeddingStore)
- .build();
+ EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
+ .documentSplitter(DocumentSplitters.recursive(30000, 200))
+ .embeddingModel(embeddingModel)
+ .embeddingStore(embeddingStore)
+ .build();
- Document document = loadDocument(toolConfig, new TextDocumentParser());
- ingestor.ingest(document);
+ Document document = loadDocument(toolConfig, new TextDocumentParser());
+ ingestor.ingest(document);
- ChatLanguageModel model = configuration.getModel();
+ ChatLanguageModel model = configuration.getModel();
- // MIGRATE CHAINS TO AI SERVICES: https://docs.langchain4j.dev/tutorials/ai-services/
- // and Specifically the RAG section: https://docs.langchain4j.dev/tutorials/ai-services#rag
- //chains are legacy now, please use AI Services: https://docs.langchain4j.dev/tutorials/ai-services > Update to AI Services
- ConversationalRetrievalChain chain = ConversationalRetrievalChain.builder()
- .chatLanguageModel(model)
- .retriever(EmbeddingStoreRetriever.from(embeddingStore, embeddingModel))
- // .chatMemory() // you can override default chat memory
- // .promptTemplate() // you can override default prompt template
- .build();
+ // MIGRATE CHAINS TO AI SERVICES: https://docs.langchain4j.dev/tutorials/ai-services/
+ // and Specifically the RAG section: https://docs.langchain4j.dev/tutorials/ai-services#rag
+ //chains are legacy now, please use AI Services: https://docs.langchain4j.dev/tutorials/ai-services > Update to AI Services
+ ConversationalRetrievalChain chain = ConversationalRetrievalChain.builder()
+ .chatLanguageModel(model)
+ .retriever(EmbeddingStoreRetriever.from(embeddingStore, embeddingModel))
+ // .chatMemory() // you can override default chat memory
+ // .promptTemplate() // you can override default prompt template
+ .build();
- String intermediateAnswer = chain.execute(data);
- String response = model.generate(data);
- List findURL = extractUrls(intermediateAnswer);
- boolean toolsUsed = false;
+ String intermediateAnswer = chain.execute(data);
+ String response = model.generate(data);
+ List findURL = extractUrls(intermediateAnswer);
+ boolean toolsUsed = false;
- if (findURL != null) {
+ if (findURL != null) {
- toolsUsed = true;
+ toolsUsed = true;
- // Create an instance of the custom tool with parameters
- GenericRestApiTool restApiTool = new GenericRestApiTool(findURL.get(0), "API Call", "Execute GET or POST Requests");
+ // Create an instance of the custom tool with parameters
+ GenericRestApiTool restApiTool = new GenericRestApiTool(findURL.get(0), "API Call", "Execute GET or POST Requests");
- // Build the assistant with the custom tool
- AssistantC assistant = AiServices.builder(AssistantC.class)
- .chatLanguageModel(model)
- .tools(restApiTool)
- //.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
- .build();
- // Use the assistant to make a query
- response = assistant.chat(intermediateAnswer);
- LOGGER.info("Response: {}", response);
- }
+ // Build the assistant with the custom tool
+ AssistantC assistant = AiServices.builder(AssistantC.class)
+ .chatLanguageModel(model)
+ .tools(restApiTool)
+ //.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
+ .build();
+ // Use the assistant to make a query
+ response = assistant.chat(intermediateAnswer);
+ LOGGER.info("Response: {}", response);
+ }
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, response);
- jsonObject.put(MuleChainConstants.TOOLS_USED, toolsUsed);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, response);
+ jsonObject.put(MuleChainConstants.TOOLS_USED, toolsUsed);
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new ToolsOperationException("Error occurred while executing AI Tools with the provided config", e);
+ }
}
@@ -361,16 +383,21 @@ private static List extractUrls(String input) {
*/
@MediaType(value = ANY, strict = false)
@Alias("EMBEDDING-new-store")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String createEmbedding(String storeName) {
- InMemoryEmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>();
+ try {
+ InMemoryEmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>();
- embeddingStore.serializeToFile(storeName);
+ embeddingStore.serializeToFile(storeName);
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
- jsonObject.put(MuleChainConstants.STATUS, MuleChainConstants.CREATED);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
+ jsonObject.put(MuleChainConstants.STATUS, MuleChainConstants.CREATED);
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new EmbeddingStoreOperationsException("Error while creating new Embedding store: " + storeName, e);
+ }
}
@@ -380,28 +407,37 @@ public String createEmbedding(String storeName) {
*/
@MediaType(value = ANY, strict = false)
@Alias("EMBEDDING-add-document-to-store")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String addFileEmbedding(String storeName, String contextPath,
@ParameterGroup(name = "Context") FileTypeParameters fileType) {
- InMemoryEmbeddingStore deserializedStore = InMemoryEmbeddingStore.fromFile(storeName);
+ try {
+ InMemoryEmbeddingStore deserializedStore = InMemoryEmbeddingStore.fromFile(storeName);
- EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
- .documentSplitter(DocumentSplitters.recursive(2000, 200))
- .embeddingModel(this.embeddingModel)
- .embeddingStore(deserializedStore)
- .build();
+ EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
+ .documentSplitter(DocumentSplitters.recursive(2000, 200))
+ .embeddingModel(this.embeddingModel)
+ .embeddingStore(deserializedStore)
+ .build();
- ingestDocument(fileType, contextPath, ingestor);
+ ingestDocument(fileType, contextPath, ingestor);
- deserializedStore.serializeToFile(storeName);
+ deserializedStore.serializeToFile(storeName);
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.FILE_TYPE, fileType.getFileType());
- jsonObject.put(MuleChainConstants.FILE_PATH, contextPath);
- jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
- jsonObject.put(MuleChainConstants.STATUS, MuleChainConstants.UPDATED);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.FILE_TYPE, fileType.getFileType());
+ jsonObject.put(MuleChainConstants.FILE_PATH, contextPath);
+ jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
+ jsonObject.put(MuleChainConstants.STATUS, MuleChainConstants.UPDATED);
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (ModuleException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new EmbeddingStoreOperationsException(String.format("Error while adding document %s to the Embedding store %s",
+ contextPath, storeName),
+ e);
+ }
}
@@ -410,56 +446,61 @@ public String addFileEmbedding(String storeName, String contextPath,
*/
@MediaType(value = ANY, strict = false)
@Alias("EMBEDDING-query-from-store")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String queryFromEmbedding(String storeName, String question, int maxResults, double minScore, boolean getLatest) {
- if (minScore == 0) {
- minScore = 0.7;
- }
-
- InMemoryEmbeddingStore store = getDeserializedStore(storeName, getLatest);
-
- Embedding questionEmbedding = this.embeddingModel.embed(question).content();
-
- List> relevantEmbeddings = store.findRelevant(questionEmbedding, maxResults, minScore);
-
- String information = relevantEmbeddings.stream()
- .map(match -> match.embedded().text())
- .collect(joining("\n\n"));
-
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.MAX_RESULTS, maxResults);
- jsonObject.put(MuleChainConstants.MIN_SCORE, minScore);
- jsonObject.put(MuleChainConstants.QUESTION, question);
- jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
- jsonObject.put(MuleChainConstants.INFORMATION, information);
-
- JSONArray sources = new JSONArray();
- String absoluteDirectoryPath;
- String fileName;
- String url;
-
- JSONObject contentObject;
- String fullPath;
- for (EmbeddingMatch match : relevantEmbeddings) {
- Metadata matchMetadata = match.embedded().metadata();
-
- fileName = matchMetadata.getString(MuleChainConstants.EmbeddingConstants.FILE_NAME);
- url = matchMetadata.getString(MuleChainConstants.URL);
- fullPath = matchMetadata.getString(MuleChainConstants.EmbeddingConstants.FULL_PATH);
- absoluteDirectoryPath = matchMetadata.getString(MuleChainConstants.EmbeddingConstants.ABSOLUTE_DIRECTORY_PATH);
-
- contentObject = new JSONObject();
- contentObject.put(MuleChainConstants.ABSOLUTE_DIRECTORY_PATH, absoluteDirectoryPath);
- contentObject.put(MuleChainConstants.FULL_PATH, fullPath);
- contentObject.put(MuleChainConstants.FILE_NAME, fileName);
- contentObject.put(MuleChainConstants.URL, url);
- contentObject.put(MuleChainConstants.INDIVIDUAL_SCORE, match.score());
- contentObject.put(MuleChainConstants.TEXT_SEGMENT, match.embedded().text());
-
- sources.put(contentObject);
+ try {
+ if (minScore == 0) {
+ minScore = 0.7;
+ }
+
+ InMemoryEmbeddingStore store = getDeserializedStore(storeName, getLatest);
+
+ Embedding questionEmbedding = this.embeddingModel.embed(question).content();
+
+ List> relevantEmbeddings = store.findRelevant(questionEmbedding, maxResults, minScore);
+
+ String information = relevantEmbeddings.stream()
+ .map(match -> match.embedded().text())
+ .collect(joining("\n\n"));
+
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.MAX_RESULTS, maxResults);
+ jsonObject.put(MuleChainConstants.MIN_SCORE, minScore);
+ jsonObject.put(MuleChainConstants.QUESTION, question);
+ jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
+ jsonObject.put(MuleChainConstants.INFORMATION, information);
+
+ JSONArray sources = new JSONArray();
+ String absoluteDirectoryPath;
+ String fileName;
+ String url;
+
+ JSONObject contentObject;
+ String fullPath;
+ for (EmbeddingMatch match : relevantEmbeddings) {
+ Metadata matchMetadata = match.embedded().metadata();
+
+ fileName = matchMetadata.getString(MuleChainConstants.EmbeddingConstants.FILE_NAME);
+ url = matchMetadata.getString(MuleChainConstants.URL);
+ fullPath = matchMetadata.getString(MuleChainConstants.EmbeddingConstants.FULL_PATH);
+ absoluteDirectoryPath = matchMetadata.getString(MuleChainConstants.EmbeddingConstants.ABSOLUTE_DIRECTORY_PATH);
+
+ contentObject = new JSONObject();
+ contentObject.put(MuleChainConstants.ABSOLUTE_DIRECTORY_PATH, absoluteDirectoryPath);
+ contentObject.put(MuleChainConstants.FULL_PATH, fullPath);
+ contentObject.put(MuleChainConstants.FILE_NAME, fileName);
+ contentObject.put(MuleChainConstants.URL, url);
+ contentObject.put(MuleChainConstants.INDIVIDUAL_SCORE, match.score());
+ contentObject.put(MuleChainConstants.TEXT_SEGMENT, match.embedded().text());
+
+ sources.put(contentObject);
+ }
+ jsonObject.put(MuleChainConstants.SOURCES, sources);
+
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new EmbeddingStoreOperationsException("Error while querying from the embedding store " + storeName, e);
}
- jsonObject.put(MuleChainConstants.SOURCES, sources);
-
- return jsonObject.toString();
}
/**
@@ -467,54 +508,59 @@ public String queryFromEmbedding(String storeName, String question, int maxResul
*/
@MediaType(value = ANY, strict = false)
@Alias("EMBEDDING-get-info-from-store")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String promptFromEmbedding(@Config LangchainLLMConfiguration configuration, String storeName, String data,
boolean getLatest) {
- InMemoryEmbeddingStore store = getDeserializedStore(storeName, getLatest);
-
- ChatLanguageModel model = configuration.getModel();
-
- ContentRetriever contentRetriever = new EmbeddingStoreContentRetriever(store, this.embeddingModel);
-
- AssistantSources assistantSources = AiServices.builder(AssistantSources.class)
- .chatLanguageModel(model)
- .contentRetriever(contentRetriever)
- .build();
-
- Result results;
- results = assistantSources.chat(data);
- List contents = results.sources();
-
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, results.content());
- jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
- jsonObject.put(MuleChainConstants.QUESTION, data);
- jsonObject.put(MuleChainConstants.GET_LATEST, getLatest);
-
- JSONArray sources = new JSONArray();
- String absoluteDirectoryPath;
- String fileName;
- String url;
- Metadata metadata;
-
- JSONObject contentObject;
- for (Content content : contents) {
- metadata = content.textSegment().metadata();
- absoluteDirectoryPath = (String) metadata.getString(MuleChainConstants.EmbeddingConstants.ABSOLUTE_DIRECTORY_PATH);
- fileName = (String) metadata.getString(MuleChainConstants.EmbeddingConstants.FILE_NAME);
- url = (String) metadata.getString(MuleChainConstants.URL);
-
- contentObject = new JSONObject();
- contentObject.put(MuleChainConstants.ABSOLUTE_DIRECTORY_PATH, absoluteDirectoryPath);
- contentObject.put(MuleChainConstants.FILE_NAME, fileName);
- contentObject.put(MuleChainConstants.URL, url);
- contentObject.put(MuleChainConstants.TEXT_SEGMENT, content.textSegment().text());
- sources.put(contentObject);
- }
- jsonObject.put(MuleChainConstants.SOURCES, sources);
- jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(results));
+ try {
+ InMemoryEmbeddingStore store = getDeserializedStore(storeName, getLatest);
+
+ ChatLanguageModel model = configuration.getModel();
+
+ ContentRetriever contentRetriever = new EmbeddingStoreContentRetriever(store, this.embeddingModel);
+
+ AssistantSources assistantSources = AiServices.builder(AssistantSources.class)
+ .chatLanguageModel(model)
+ .contentRetriever(contentRetriever)
+ .build();
- return jsonObject.toString();
+ Result results;
+ results = assistantSources.chat(data);
+ List contents = results.sources();
+
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, results.content());
+ jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
+ jsonObject.put(MuleChainConstants.QUESTION, data);
+ jsonObject.put(MuleChainConstants.GET_LATEST, getLatest);
+
+ JSONArray sources = new JSONArray();
+ String absoluteDirectoryPath;
+ String fileName;
+ String url;
+ Metadata metadata;
+
+ JSONObject contentObject;
+ for (Content content : contents) {
+ metadata = content.textSegment().metadata();
+ absoluteDirectoryPath = (String) metadata.getString(MuleChainConstants.EmbeddingConstants.ABSOLUTE_DIRECTORY_PATH);
+ fileName = (String) metadata.getString(MuleChainConstants.EmbeddingConstants.FILE_NAME);
+ url = (String) metadata.getString(MuleChainConstants.URL);
+
+ contentObject = new JSONObject();
+ contentObject.put(MuleChainConstants.ABSOLUTE_DIRECTORY_PATH, absoluteDirectoryPath);
+ contentObject.put(MuleChainConstants.FILE_NAME, fileName);
+ contentObject.put(MuleChainConstants.URL, url);
+ contentObject.put(MuleChainConstants.TEXT_SEGMENT, content.textSegment().text());
+ sources.put(contentObject);
+ }
+ jsonObject.put(MuleChainConstants.SOURCES, sources);
+ jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(results));
+
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new EmbeddingStoreOperationsException(String.format("Error while getting info from the store %s", storeName), e);
+ }
}
interface AssistantSources {
@@ -527,26 +573,31 @@ interface AssistantSources {
*/
@MediaType(value = ANY, strict = false)
@Alias("EMBEDDING-get-info-from-store-legacy")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String promptFromEmbeddingLegacy(@Config LangchainLLMConfiguration configuration, String storeName, String data,
boolean getLatest) {
- InMemoryEmbeddingStore store = getDeserializedStore(storeName, getLatest);
+ try {
+ InMemoryEmbeddingStore store = getDeserializedStore(storeName, getLatest);
- ChatLanguageModel model = configuration.getModel();
+ ChatLanguageModel model = configuration.getModel();
- ConversationalRetrievalChain chain = ConversationalRetrievalChain.builder()
- .chatLanguageModel(model)
- .retriever(EmbeddingStoreRetriever.from(store, this.embeddingModel))
- .build();
+ ConversationalRetrievalChain chain = ConversationalRetrievalChain.builder()
+ .chatLanguageModel(model)
+ .retriever(EmbeddingStoreRetriever.from(store, this.embeddingModel))
+ .build();
- String answer = chain.execute(data);
+ String answer = chain.execute(data);
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, answer);
- jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
- jsonObject.put(MuleChainConstants.GET_LATEST, getLatest);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, answer);
+ jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
+ jsonObject.put(MuleChainConstants.GET_LATEST, getLatest);
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new EmbeddingStoreOperationsException(String.format("Error while getting info from the store %s", storeName), e);
+ }
}
@@ -561,54 +612,58 @@ interface AssistantEmbedding {
*/
@MediaType(value = ANY, strict = false)
@Alias("TOOLS-use-ai-service")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String useAIServiceTools(@Config LangchainLLMConfiguration configuration, String data, String toolConfig) {
+ try {
+ EmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>();
- EmbeddingStore embeddingStore = new InMemoryEmbeddingStore<>();
-
- EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
- .documentSplitter(DocumentSplitters.recursive(30000, 200))
- .embeddingModel(embeddingModel)
- .embeddingStore(embeddingStore)
- .build();
-
- Document document = loadDocument(toolConfig, new TextDocumentParser());
- ingestor.ingest(document);
-
- ChatLanguageModel model = configuration.getModel();
- ContentRetriever contentRetriever = new EmbeddingStoreContentRetriever(embeddingStore, embeddingModel);
-
- AssistantEmbedding assistant = AiServices.builder(AssistantEmbedding.class)
- .chatLanguageModel(model)
- .contentRetriever(contentRetriever)
- .build();
-
- String intermediateAnswer = assistant.chat(data);
- String response = model.generate(data);
- List findURL = extractUrls(intermediateAnswer);
- boolean toolsUsed = false;
+ EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
+ .documentSplitter(DocumentSplitters.recursive(30000, 200))
+ .embeddingModel(embeddingModel)
+ .embeddingStore(embeddingStore)
+ .build();
- if (findURL != null) {
+ Document document = loadDocument(toolConfig, new TextDocumentParser());
+ ingestor.ingest(document);
- toolsUsed = true;
- // Create an instance of the custom tool with parameters
- GenericRestApiTool restApiTool = new GenericRestApiTool(findURL.get(0), "API Call", "Execute GET or POST Requests");
+ ChatLanguageModel model = configuration.getModel();
+ ContentRetriever contentRetriever = new EmbeddingStoreContentRetriever(embeddingStore, embeddingModel);
- // Build the assistant with the custom tool
- AssistantC assistantC = AiServices.builder(AssistantC.class)
+ AssistantEmbedding assistant = AiServices.builder(AssistantEmbedding.class)
.chatLanguageModel(model)
- .tools(restApiTool)
- //.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
+ .contentRetriever(contentRetriever)
.build();
- // Use the assistant to make a query
- response = assistantC.chat(intermediateAnswer);
- LOGGER.info("Response: {}", response);
- }
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, response);
- jsonObject.put(MuleChainConstants.TOOLS_USED, toolsUsed);
-
- return jsonObject.toString();
+ String intermediateAnswer = assistant.chat(data);
+ String response = model.generate(data);
+ List findURL = extractUrls(intermediateAnswer);
+ boolean toolsUsed = false;
+
+ if (findURL != null) {
+
+ toolsUsed = true;
+ // Create an instance of the custom tool with parameters
+ GenericRestApiTool restApiTool = new GenericRestApiTool(findURL.get(0), "API Call", "Execute GET or POST Requests");
+
+ // Build the assistant with the custom tool
+ AssistantC assistantC = AiServices.builder(AssistantC.class)
+ .chatLanguageModel(model)
+ .tools(restApiTool)
+ //.chatMemory(MessageWindowChatMemory.withMaxMessages(10))
+ .build();
+ // Use the assistant to make a query
+ response = assistantC.chat(intermediateAnswer);
+ LOGGER.info("Response: {}", response);
+ }
+
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, response);
+ jsonObject.put(MuleChainConstants.TOOLS_USED, toolsUsed);
+
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new ToolsOperationException("Error occurred while executing AI Tools with the provided config", e);
+ }
}
@@ -617,63 +672,73 @@ public String useAIServiceTools(@Config LangchainLLMConfiguration configuration,
*/
@MediaType(value = ANY, strict = false)
@Alias("EMBEDDING-add-folder-to-store")
+ @Throws(EmbeddingErrorTypeProvider.class)
public String addFilesFromFolderEmbedding(String storeName, String contextPath,
@ParameterGroup(name = "Context") FileTypeParameters fileType) {
- InMemoryEmbeddingStore deserializedStore = InMemoryEmbeddingStore.fromFile(storeName);
-
- EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
- .documentSplitter(DocumentSplitters.recursive(2000, 200))
- .embeddingModel(this.embeddingModel)
- .embeddingStore(deserializedStore)
- .build();
-
- long totalFiles = 0;
- try (Stream paths = Files.walk(Paths.get(contextPath))) {
- totalFiles = paths.filter(Files::isRegularFile).count();
- } catch (IOException e) {
- LOGGER.error("Unable to load files in the path: " + contextPath, e);
- }
+ try {
+ InMemoryEmbeddingStore deserializedStore = InMemoryEmbeddingStore.fromFile(storeName);
- LOGGER.info("Total number of files to process: {}", totalFiles);
- AtomicInteger fileCounter = new AtomicInteger(0);
- try (Stream paths = Files.walk(Paths.get(contextPath))) {
- paths.filter(Files::isRegularFile).forEach(file -> {
- int currentFileCounter = fileCounter.incrementAndGet();
- LOGGER.info("Processing file {}: {}", currentFileCounter, file.getFileName());
- Document document = null;
- try {
- switch (FileType.fromValue(fileType.getFileType())) {
- case TEXT:
- document = loadDocument(file.toString(), new TextDocumentParser());
- ingestor.ingest(document);
- break;
- case PDF:
- document = loadDocument(file.toString(), new ApacheTikaDocumentParser());
- ingestor.ingest(document);
- break;
- case URL:
- // Handle URLs separately if needed
- break;
- default:
- throw new IllegalArgumentException("Unsupported File Type: " + fileType.getFileType());
+ EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
+ .documentSplitter(DocumentSplitters.recursive(2000, 200))
+ .embeddingModel(this.embeddingModel)
+ .embeddingStore(deserializedStore)
+ .build();
+
+ long totalFiles = 0;
+ try (Stream paths = Files.walk(Paths.get(contextPath))) {
+ totalFiles = paths.filter(Files::isRegularFile).count();
+ } catch (IOException e) {
+ LOGGER.error("Unable to load files in the path: " + contextPath, e);
+ }
+
+ LOGGER.info("Total number of files to process: {}", totalFiles);
+ AtomicInteger fileCounter = new AtomicInteger(0);
+ try (Stream paths = Files.walk(Paths.get(contextPath))) {
+ paths.filter(Files::isRegularFile).forEach(file -> {
+ int currentFileCounter = fileCounter.incrementAndGet();
+ LOGGER.info("Processing file {}: {}", currentFileCounter, file.getFileName());
+ Document document = null;
+ try {
+ switch (FileType.fromValue(fileType.getFileType())) {
+ case TEXT:
+ document = loadDocument(file.toString(), new TextDocumentParser());
+ ingestor.ingest(document);
+ break;
+ case PDF:
+ document = loadDocument(file.toString(), new ApacheTikaDocumentParser());
+ ingestor.ingest(document);
+ break;
+ case URL:
+ // Handle URLs separately if needed
+ break;
+ default:
+ throw new FileHandlingException("Unsupported File Type: " + fileType.getFileType());
+ }
+ } catch (BlankDocumentException e) {
+ LOGGER.warn("Skipping file due to BlankDocumentException: {}", file.getFileName());
}
- } catch (BlankDocumentException e) {
- LOGGER.warn("Skipping file due to BlankDocumentException: {}", file.getFileName());
- }
- });
- } catch (IOException e) {
- LOGGER.error("Exception occurred while loading files: " + contextPath, e);
+ });
+ } catch (IOException e) {
+ LOGGER.error("Exception occurred while loading files: " + contextPath, e);
+ throw new FileHandlingException("Exception occurred while loading files: " + contextPath, e);
+ }
+
+ deserializedStore.serializeToFile(storeName);
+
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.FILES_COUNT, totalFiles);
+ jsonObject.put(MuleChainConstants.FOLDER_PATH, contextPath);
+ jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
+ jsonObject.put(MuleChainConstants.STATUS, MuleChainConstants.UPDATED);
+
+ return jsonObject.toString();
+ } catch (ModuleException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new EmbeddingStoreOperationsException(String.format("Error while adding folder %s into the store %s", contextPath,
+ storeName),
+ e);
}
-
- deserializedStore.serializeToFile(storeName);
-
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.FILES_COUNT, totalFiles);
- jsonObject.put(MuleChainConstants.FOLDER_PATH, contextPath);
- jsonObject.put(MuleChainConstants.STORE_NAME, storeName);
- jsonObject.put(MuleChainConstants.STATUS, MuleChainConstants.UPDATED);
-
- return jsonObject.toString();
}
}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainImageModelsOperations.java b/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainImageModelsOperations.java
index e771c53..a0ee009 100644
--- a/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainImageModelsOperations.java
+++ b/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainImageModelsOperations.java
@@ -7,9 +7,15 @@
import org.json.JSONObject;
import org.mule.extension.mulechain.internal.config.LangchainLLMConfiguration;
import org.mule.extension.mulechain.internal.constants.MuleChainConstants;
+import org.mule.extension.mulechain.internal.error.provider.ImageErrorTypeProvider;
+import org.mule.extension.mulechain.internal.exception.FileHandlingException;
+import org.mule.extension.mulechain.internal.exception.image.ImageAnalyzerException;
+import org.mule.extension.mulechain.internal.exception.image.ImageGenerationException;
+import org.mule.extension.mulechain.internal.exception.image.ImageProcessingException;
import org.mule.extension.mulechain.internal.llm.config.ConfigExtractor;
import org.mule.extension.mulechain.internal.util.JsonUtils;
import org.mule.runtime.extension.api.annotation.Alias;
+import org.mule.runtime.extension.api.annotation.error.Throws;
import org.mule.runtime.extension.api.annotation.param.MediaType;
import org.mule.runtime.extension.api.annotation.param.Config;
@@ -24,13 +30,15 @@
import dev.langchain4j.data.message.TextContent;
import dev.langchain4j.data.message.UserMessage;
import dev.langchain4j.model.chat.ChatLanguageModel;
+import org.mule.sdk.api.exception.ModuleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.Base64;
import javax.imageio.ImageIO;
@@ -51,21 +59,27 @@ public class LangchainImageModelsOperations {
*/
@MediaType(value = ANY, strict = false)
@Alias("IMAGE-read")
+ @Throws(ImageErrorTypeProvider.class)
public String readFromImage(@Config LangchainLLMConfiguration configuration, String data, String contextURL) {
+ try {
+ ChatLanguageModel model = configuration.getModel();
- ChatLanguageModel model = configuration.getModel();
-
- UserMessage userMessage = UserMessage.from(
- TextContent.from(data),
- ImageContent.from(contextURL));
+ UserMessage userMessage = UserMessage.from(
+ TextContent.from(data),
+ ImageContent.from(contextURL));
- Response response = model.generate(userMessage);
+ Response response = model.generate(userMessage);
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, response.content().text());
- jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(response));
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, response.content().text());
+ jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(response));
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new ImageAnalyzerException(String.format("Unable to analyze the provided image %s with the text: %s", contextURL,
+ data),
+ e);
+ }
}
/**
@@ -73,53 +87,56 @@ public String readFromImage(@Config LangchainLLMConfiguration configuration, Str
*/
@MediaType(value = ANY, strict = false)
@Alias("IMAGE-generate")
+ @Throws(ImageErrorTypeProvider.class)
public String drawImage(@Config LangchainLLMConfiguration configuration, String data) {
- ConfigExtractor configExtractor = configuration.getConfigExtractor();
- ImageModel model = OpenAiImageModel.builder()
- .modelName(configuration.getModelName())
- .apiKey(configExtractor.extractValue("OPENAI_API_KEY"))
- .build();
-
- Response response = model.generate(data);
- LOGGER.info("Generated Image: {}", response.content().url());
-
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, response.content().url());
-
- return jsonObject.toString();
+ try {
+ ConfigExtractor configExtractor = configuration.getConfigExtractor();
+ ImageModel model = OpenAiImageModel.builder()
+ .modelName(configuration.getModelName())
+ .apiKey(configExtractor.extractValue("OPENAI_API_KEY"))
+ .build();
+
+ Response response = model.generate(data);
+ LOGGER.info("Generated Image: {}", response.content().url());
+
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, response.content().url());
+
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new ImageGenerationException("Error while generating the required image: " + data, e);
+ }
}
/**
- * Reads an scanned document.
+ * Reads a scanned document.
*/
@MediaType(value = ANY, strict = false)
@Alias("IMAGE-read-scanned-documents")
+ @Throws(ImageErrorTypeProvider.class)
public String readScannedDocumentPDF(@Config LangchainLLMConfiguration configuration, String data, String filePath) {
ChatLanguageModel model = configuration.getModel();
- String sourceDir = filePath;
-
JSONObject jsonObject = new JSONObject();
JSONArray docPages = new JSONArray();
//try (PDDocument document = Loader.loadPDF(new File(sourceDir))) {
- try (InputStream inputStream = new FileInputStream(sourceDir);
+ try (InputStream inputStream = Files.newInputStream(Paths.get(filePath));
PDDocument document = PDDocument.load(inputStream);) {
-
PDFRenderer pdfRenderer = new PDFRenderer(document);
int totalPages = document.getNumberOfPages();
- LOGGER.info("Total files to be converted -> " + totalPages);
+ LOGGER.info("Total files to be converted -> {}", totalPages);
jsonObject.put(MuleChainConstants.TOTAL_PAGES, totalPages);
JSONObject docPage;
for (int pageNumber = 0; pageNumber < totalPages; pageNumber++) {
BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 300);
- LOGGER.info("Reading page -> " + pageNumber);
+ LOGGER.info("Reading page -> {}", pageNumber);
String imageBase64 = convertToBase64String(image);
UserMessage userMessage = UserMessage.from(
@@ -136,7 +153,14 @@ public String readScannedDocumentPDF(@Config LangchainLLMConfiguration configura
}
} catch (IOException e) {
- LOGGER.info("Error occurred while processing the file: " + e.getMessage());
+ LOGGER.error("Error occurred in processing the document: " + filePath, e);
+ throw new FileHandlingException("Error occurred while processing the document file: " + filePath, e);
+ } catch (ModuleException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ImageAnalyzerException(String.format("Unable to analyze the provided document %s with the text: %s", filePath,
+ data),
+ e);
}
jsonObject.put(MuleChainConstants.PAGES, docPages);
@@ -152,9 +176,7 @@ private String convertToBase64String(BufferedImage image) {
base64String = Base64.getEncoder().encodeToString(imageBytes);
return base64String;
} catch (IOException e) {
- e.printStackTrace();
- LOGGER.info("Error occurred while processing the file: " + e.getMessage());
- return "Error";
+ throw new ImageProcessingException("Error occurred while processing the image", e);
}
}
}
diff --git a/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainLLMOperations.java b/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainLLMOperations.java
index 9a44a41..cd6ef19 100644
--- a/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainLLMOperations.java
+++ b/src/main/java/org/mule/extension/mulechain/internal/operation/LangchainLLMOperations.java
@@ -13,8 +13,13 @@
import org.json.JSONObject;
import org.mule.extension.mulechain.internal.config.LangchainLLMConfiguration;
import org.mule.extension.mulechain.internal.constants.MuleChainConstants;
+import org.mule.extension.mulechain.internal.error.provider.AiServiceErrorTypeProvider;
+import org.mule.extension.mulechain.internal.exception.ChatException;
+import org.mule.extension.mulechain.internal.exception.PromptTemplateException;
+import org.mule.extension.mulechain.internal.exception.SentimentAnalyzerException;
import org.mule.extension.mulechain.internal.util.JsonUtils;
import org.mule.runtime.extension.api.annotation.Alias;
+import org.mule.runtime.extension.api.annotation.error.Throws;
import org.mule.runtime.extension.api.annotation.param.Config;
import org.mule.runtime.extension.api.annotation.param.MediaType;
import dev.langchain4j.model.input.Prompt;
@@ -42,50 +47,58 @@ interface Assistant {
*/
@MediaType(value = ANY, strict = false)
@Alias("CHAT-answer-prompt")
+ @Throws(AiServiceErrorTypeProvider.class)
public String answerPromptByModelName(@Config LangchainLLMConfiguration configuration, String prompt) {
// OpenAI parameters are explained here: https://platform.openai.com/docs/api-reference/chat/create
- ChatLanguageModel model = configuration.getModel();
+ try {
+ ChatLanguageModel model = configuration.getModel();
+ Assistant assistant = AiServices.create(Assistant.class, model);
+ Result answer = assistant.chat(prompt);
- Assistant assistant = AiServices.create(Assistant.class, model);
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, answer.content());
+ jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(answer));
- Result answer = assistant.chat(prompt);
-
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, answer.content());
- jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(answer));
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new ChatException("Unable to respond with the chat provided", e);
+ }
}
/**
- * Helps defining an AI Agent with a prompt template
+ * Helps in defining an AI Agent with a prompt template
*/
@MediaType(value = ANY, strict = false)
@Alias("AGENT-define-prompt-template")
+ @Throws(AiServiceErrorTypeProvider.class)
public String definePromptTemplate(@Config LangchainLLMConfiguration configuration, String template, String instructions,
String dataset) {
- ChatLanguageModel model = configuration.getModel();
+ try {
+ ChatLanguageModel model = configuration.getModel();
- PromptTemplate promptTemplate = PromptTemplate.from(template + System.lineSeparator() + "Instructions: {{instructions}}"
- + System.lineSeparator() + "Dataset: {{dataset}}");
+ PromptTemplate promptTemplate = PromptTemplate.from(template + System.lineSeparator() + "Instructions: {{instructions}}"
+ + System.lineSeparator() + "Dataset: {{dataset}}");
- Map variables = new HashMap<>();
- variables.put(MuleChainConstants.INSTRUCTIONS, instructions);
- variables.put(MuleChainConstants.DATASET, dataset);
+ Map variables = new HashMap<>();
+ variables.put(MuleChainConstants.INSTRUCTIONS, instructions);
+ variables.put(MuleChainConstants.DATASET, dataset);
- Prompt prompt = promptTemplate.apply(variables);
+ Prompt prompt = promptTemplate.apply(variables);
- //String response = model.generate(prompt.text());
- Assistant assistant = AiServices.create(Assistant.class, model);
+ Assistant assistant = AiServices.create(Assistant.class, model);
- Result answer = assistant.chat(prompt.text());
+ Result answer = assistant.chat(prompt.text());
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.RESPONSE, answer.content());
- jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(answer));
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.RESPONSE, answer.content());
+ jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(answer));
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new PromptTemplateException("Unable to reply with the correct prompt template", e);
+ }
}
/**
@@ -109,24 +122,29 @@ interface SentimentAnalyzer {
*/
@MediaType(value = ANY, strict = false)
@Alias("SENTIMENT-analyze")
+ @Throws(AiServiceErrorTypeProvider.class)
public String extractSentiments(@Config LangchainLLMConfiguration configuration, String data) {
- ChatLanguageModel model = configuration.getModel();
+ try {
+ ChatLanguageModel model = configuration.getModel();
- SentimentAnalyzer sentimentAnalyzer = AiServices.create(SentimentAnalyzer.class, model);
+ SentimentAnalyzer sentimentAnalyzer = AiServices.create(SentimentAnalyzer.class, model);
- Result sentiment = sentimentAnalyzer.analyzeSentimentOf(data);
- LOGGER.info("Analyzed sentiment: {}", sentiment); // POSITIVE
+ Result sentiment = sentimentAnalyzer.analyzeSentimentOf(data);
+ LOGGER.info("Analyzed sentiment: {}", sentiment); // POSITIVE
- boolean positive = sentimentAnalyzer.isPositive(data);
- LOGGER.info("Is sentiment positive: {}", positive); // false
+ boolean positive = sentimentAnalyzer.isPositive(data);
+ LOGGER.info("Is sentiment positive: {}", positive); // false
- JSONObject jsonObject = new JSONObject();
- jsonObject.put(MuleChainConstants.SENTIMENT, sentiment.content());
- jsonObject.put(MuleChainConstants.IS_POSITIVE, positive);
- jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(sentiment));
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put(MuleChainConstants.SENTIMENT, sentiment.content());
+ jsonObject.put(MuleChainConstants.IS_POSITIVE, positive);
+ jsonObject.put(MuleChainConstants.TOKEN_USAGE, JsonUtils.getTokenUsage(sentiment));
- return jsonObject.toString();
+ return jsonObject.toString();
+ } catch (Exception e) {
+ throw new SentimentAnalyzerException("Unable to provide the correct sentiments", e);
+ }
}