From 78ae8f20060555df0f06b789515118092d87a732 Mon Sep 17 00:00:00 2001
From: ali <117142933+muhammad-ali-e@users.noreply.github.com>
Date: Wed, 3 Jul 2024 11:00:02 +0530
Subject: [PATCH 01/31] Handling grpc.StatusCode.NOT_FOUND exception (#439)
* Handling grpc.StatusCode.NOT_FOUND exception seperately from other codes
* minor changes
---
.../flags/src/unstract/flags/client/evaluation.py | 13 +++++++++----
unstract/flags/src/unstract/flags/feature_flag.py | 3 +--
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/unstract/flags/src/unstract/flags/client/evaluation.py b/unstract/flags/src/unstract/flags/client/evaluation.py
index fa5347289..3a4b2b785 100644
--- a/unstract/flags/src/unstract/flags/client/evaluation.py
+++ b/unstract/flags/src/unstract/flags/client/evaluation.py
@@ -51,8 +51,13 @@ def boolean_evaluate_feature_flag(
response = self.stub.Boolean(request)
return bool(response.enabled)
except grpc.RpcError as e:
- logger.warning(
- f"Error evaluating feature flag '{flag_key}' for {namespace_key}"
- f": {str(e)}"
- )
+ if e.code() == grpc.StatusCode.NOT_FOUND:
+ logger.warning(
+ f"Flag key {flag_key} not found in namespace {namespace_key}."
+ )
+ else:
+ logger.warning(
+ f"Error evaluating feature flag {flag_key} for {namespace_key}"
+ f" : {str(e)}"
+ )
return False
diff --git a/unstract/flags/src/unstract/flags/feature_flag.py b/unstract/flags/src/unstract/flags/feature_flag.py
index 9133ba826..3094c00ca 100644
--- a/unstract/flags/src/unstract/flags/feature_flag.py
+++ b/unstract/flags/src/unstract/flags/feature_flag.py
@@ -38,6 +38,5 @@ def check_feature_flag_status(
context=context,
)
return bool(response) # Wrap the response in a boolean check
- except Exception as e:
- logger.warning(f"Error evaluating feature flag '{flag_key}': {str(e)}")
+ except Exception:
return False
From a8905f833d55476b4cd95024f05e88434ea5a6a3 Mon Sep 17 00:00:00 2001
From: Tahier Hussain <89440263+tahierhussain@users.noreply.github.com>
Date: Wed, 3 Jul 2024 13:25:37 +0530
Subject: [PATCH 02/31] FEAT: Refactored Existing Prompt Studio Component to
Support Simple Prompt Studio (#437)
* Refactored the CombinedOutput component to support both JSON and Table view
* Refactored the ToolsMain component to support SPS
* Refactored the components in order to be re-used for SPS
* Removed duplicated CSS class
* Implemented a separate function to return the /prompt URL
---
.../combined-output/CombinedOutput.jsx | 48 ++--
.../custom-tools/combined-output/JsonView.jsx | 34 +++
.../document-manager/DocumentManager.jsx | 195 ++++++++-----
.../document-parser/DocumentParser.jsx | 26 +-
.../custom-tools/prompt-card/PrompDnd.jsx | 4 +-
.../custom-tools/prompt-card/PromptCard.jsx | 88 ++++--
.../prompt-card/PromptCardItems.jsx | 261 +++++++++---------
.../custom-tools/tools-main/ToolsMain.jsx | 85 ++----
.../tools-main/ToolsMainActionBtns.jsx | 68 +++++
.../helpers/custom-tools/CustomToolsHelper.js | 1 +
frontend/src/helpers/GetStaticData.js | 12 +
frontend/src/index.css | 22 ++
frontend/src/routes/Router.jsx | 41 ++-
frontend/src/setupProxy.js | 7 +
frontend/src/store/custom-tool-store.js | 1 +
15 files changed, 585 insertions(+), 308 deletions(-)
create mode 100644 frontend/src/components/custom-tools/combined-output/JsonView.jsx
create mode 100644 frontend/src/components/custom-tools/tools-main/ToolsMainActionBtns.jsx
diff --git a/frontend/src/components/custom-tools/combined-output/CombinedOutput.jsx b/frontend/src/components/custom-tools/combined-output/CombinedOutput.jsx
index 507bf6704..4b0cb5281 100644
--- a/frontend/src/components/custom-tools/combined-output/CombinedOutput.jsx
+++ b/frontend/src/components/custom-tools/combined-output/CombinedOutput.jsx
@@ -1,4 +1,3 @@
-import Prism from "prismjs";
import "prismjs/components/prism-json";
import "prismjs/plugins/line-numbers/prism-line-numbers.css";
import "prismjs/plugins/line-numbers/prism-line-numbers.js";
@@ -17,7 +16,18 @@ import { useSessionStore } from "../../../store/session-store";
import { SpinnerLoader } from "../../widgets/spinner-loader/SpinnerLoader";
import "./CombinedOutput.css";
import { useExceptionHandler } from "../../../hooks/useExceptionHandler";
-
+import { JsonView } from "./JsonView";
+
+let TableView;
+let promptOutputApiSps;
+try {
+ TableView =
+ require("../../../plugins/simple-prompt-studio/TableView").TableView;
+ promptOutputApiSps =
+ require("../../../plugins/simple-prompt-studio/helper").promptOutputApiSps;
+} catch {
+ // The component will remain null of it is not available
+}
function CombinedOutput({ docId, setFilledFields }) {
const [combinedOutput, setCombinedOutput] = useState({});
const [isOutputLoading, setIsOutputLoading] = useState(false);
@@ -26,6 +36,7 @@ function CombinedOutput({ docId, setFilledFields }) {
defaultLlmProfile,
singlePassExtractMode,
isSinglePassExtractLoading,
+ isSimplePromptStudio,
} = useCustomToolStore();
const { sessionDetails } = useSessionStore();
const { setAlertDetails } = useAlertStore();
@@ -91,14 +102,14 @@ function CombinedOutput({ docId, setFilledFields }) {
});
}, [docId, singlePassExtractMode, isSinglePassExtractLoading]);
- useEffect(() => {
- Prism.highlightAll();
- }, [combinedOutput]);
-
const handleOutputApiRequest = async () => {
+ let url = `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/prompt-output/?tool_id=${details?.tool_id}&document_manager=${docId}&is_single_pass_extract=${singlePassExtractMode}`;
+ if (isSimplePromptStudio) {
+ url = promptOutputApiSps(details?.tool_id, null, docId);
+ }
const requestOptions = {
method: "GET",
- url: `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/prompt-output/?tool_id=${details?.tool_id}&document_manager=${docId}&is_single_pass_extract=${singlePassExtractMode}`,
+ url,
headers: {
"X-CSRFToken": sessionDetails?.csrfToken,
},
@@ -115,24 +126,11 @@ function CombinedOutput({ docId, setFilledFields }) {
return
-
- {JSON.stringify(combinedOutput, null, 2)}
-
-
- )}
-
+
+ {JSON.stringify(combinedOutput, null, 2)}
+
+
+ )}
+ @@ -29,6 +49,11 @@ function JsonView({ combinedOutput }) { JsonView.propTypes = { combinedOutput: PropTypes.object.isRequired, + handleTabChange: PropTypes.func, + adapterData: PropTypes.array, + selectedProfile: PropTypes.string, + llmProfiles: PropTypes.array, + activeKey: PropTypes.string, }; export { JsonView }; diff --git a/frontend/src/components/custom-tools/output-for-doc-modal/OutputForDocModal.jsx b/frontend/src/components/custom-tools/output-for-doc-modal/OutputForDocModal.jsx index cc4d6d6f8..23de585e2 100644 --- a/frontend/src/components/custom-tools/output-for-doc-modal/OutputForDocModal.jsx +++ b/frontend/src/components/custom-tools/output-for-doc-modal/OutputForDocModal.jsx @@ -1,4 +1,4 @@ -import { Button, Modal, Table, Typography } from "antd"; +import { Button, Modal, Table, Tabs, Typography } from "antd"; import PropTypes from "prop-types"; import { useEffect, useState } from "react"; import { @@ -12,12 +12,17 @@ import { useCustomToolStore } from "../../../store/custom-tool-store"; import { useSessionStore } from "../../../store/session-store"; import { useAxiosPrivate } from "../../../hooks/useAxiosPrivate"; import "./OutputForDocModal.css"; -import { displayPromptResult } from "../../../helpers/GetStaticData"; +import { + displayPromptResult, + getLLMModelNamesForProfiles, +} from "../../../helpers/GetStaticData"; import { SpinnerLoader } from "../../widgets/spinner-loader/SpinnerLoader"; import { useAlertStore } from "../../../store/alert-store"; import { useExceptionHandler } from "../../../hooks/useExceptionHandler"; import { TokenUsage } from "../token-usage/TokenUsage"; import { useTokenUsageStore } from "../../../store/token-usage-store"; +import TabPane from "antd/es/tabs/TabPane"; +import { ProfileInfoBar } from "../profile-info-bar/ProfileInfoBar"; const columns = [ { @@ -57,6 +62,7 @@ function OutputForDocModal({ }) { const [promptOutputs, setPromptOutputs] = useState([]); const [rows, setRows] = useState([]); + const [adapterData, setAdapterData] = useState([]); const [isLoading, setIsLoading] = useState(false); const { details, @@ -66,6 +72,7 @@ function OutputForDocModal({ disableLlmOrDocChange, singlePassExtractMode, isSinglePassExtractLoading, + llmProfiles, } = useCustomToolStore(); const { sessionDetails } = useSessionStore(); const axiosPrivate = useAxiosPrivate(); @@ -73,12 +80,14 @@ function OutputForDocModal({ const { setAlertDetails } = useAlertStore(); const { handleException } = useExceptionHandler(); const { tokenUsage } = useTokenUsageStore(); + const [selectedProfile, setSelectedProfile] = useState(defaultLlmProfile); useEffect(() => { if (!open) { return; } handleGetOutputForDocs(); + getAdapterInfo(); }, [open, singlePassExtractMode, isSinglePassExtractLoading]); useEffect(() => { @@ -89,6 +98,12 @@ function OutputForDocModal({ handleRowsGeneration(promptOutputs); }, [promptOutputs, tokenUsage]); + useEffect(() => { + if (selectedProfile) { + handleGetOutputForDocs(selectedProfile); + } + }, [selectedProfile]); + const moveSelectedDocToTop = () => { // Create a copy of the list of documents const docs = [...listOfDocs]; @@ -147,8 +162,16 @@ function OutputForDocModal({ }); }; - const handleGetOutputForDocs = () => { - let profile = profileManagerId; + const getAdapterInfo = () => { + axiosPrivate + .get(`/api/v1/unstract/${sessionDetails.orgId}/adapter/?adapter_type=LLM`) + .then((res) => { + const adapterList = res.data; + setAdapterData(getLLMModelNamesForProfiles(llmProfiles, adapterList)); + }); + }; + + const handleGetOutputForDocs = (profile = profileManagerId) => { if (singlePassExtractMode) { profile = defaultLlmProfile; } @@ -206,10 +229,14 @@ function OutputForDocModal({ } const result = { - key: item, + key: item?.document_id, document: item?.document_name, token_count: ( -+ ), value: ( <> @@ -239,6 +266,14 @@ function OutputForDocModal({ setRows(rowsData); }; + const handleTabChange = (key) => { + if (key === "0") { + setSelectedProfile(profileManagerId); + } else { + setSelectedProfile(adapterData[key - 1]?.profile_id); + } + }; + return (
Profile not found
; + } + + return ( +No chunks founds
; + } + return ( + <> + {chunk?.map((line) => ( +