-
-
-
-
- {details?.tool_name}
-
-
-
-
+ {isPublicSource ? (
+
+
+ {details?.tool_name}
+
+
+ ) : (
+
+ )}
{SinglePassToggleSwitch && (
@@ -167,6 +169,10 @@ function Header({ setOpenSettings, handleUpdateTool }) {
/>
+ {CloneButton &&
}
+ {PromptShareButton && (
+
+ )}
@@ -174,6 +180,7 @@ function Header({ setOpenSettings, handleUpdateTool }) {
type="primary"
onClick={() => handleShare(true)}
loading={isExportLoading}
+ disabled={isPublicSource}
>
@@ -195,6 +202,8 @@ function Header({ setOpenSettings, handleUpdateTool }) {
Header.propTypes = {
setOpenSettings: PropTypes.func.isRequired,
handleUpdateTool: PropTypes.func.isRequired,
+ setOpenCloneModal: PropTypes.func.isRequired,
+ setOpenShareModal: PropTypes.func.isRequired,
};
export { Header };
diff --git a/frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx b/frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx
index e82457114..49ff09bbf 100644
--- a/frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx
+++ b/frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx
@@ -75,6 +75,7 @@ function ManageDocsModal({
rawIndexStatus,
summarizeIndexStatus,
isSinglePassExtractLoading,
+ isPublicSource,
} = useCustomToolStore();
const { messages } = useSocketCustomToolStore();
const axiosPrivate = useAxiosPrivate();
@@ -137,10 +138,9 @@ function ManageDocsModal({
}, [defaultLlmProfile, details]);
useEffect(() => {
- if (!open) {
+ if (!open || isPublicSource) {
return;
}
-
handleGetIndexStatus(rawLlmProfile, indexTypes.raw);
}, [indexDocs, rawLlmProfile, open]);
@@ -384,7 +384,8 @@ function ManageDocsModal({
isSinglePassExtractLoading ||
indexDocs.includes(item?.document_id) ||
isUploading ||
- !defaultLlmProfile
+ !defaultLlmProfile ||
+ isPublicSource
}
/>
@@ -408,7 +409,8 @@ function ManageDocsModal({
disableLlmOrDocChange?.length > 0 ||
isSinglePassExtractLoading ||
indexDocs.includes(item?.document_id) ||
- isUploading
+ isUploading ||
+ isPublicSource
}
>
@@ -423,7 +425,8 @@ function ManageDocsModal({
disabled={
disableLlmOrDocChange?.length > 0 ||
isSinglePassExtractLoading ||
- indexDocs.includes(item?.document_id)
+ indexDocs.includes(item?.document_id) ||
+ isPublicSource
}
/>
),
diff --git a/frontend/src/components/custom-tools/manage-llm-profiles/ManageLlmProfiles.jsx b/frontend/src/components/custom-tools/manage-llm-profiles/ManageLlmProfiles.jsx
index c49b40c80..643abe2e3 100644
--- a/frontend/src/components/custom-tools/manage-llm-profiles/ManageLlmProfiles.jsx
+++ b/frontend/src/components/custom-tools/manage-llm-profiles/ManageLlmProfiles.jsx
@@ -65,8 +65,13 @@ function ManageLlmProfiles() {
const [editLlmProfileId, setEditLlmProfileId] = useState(null);
const axiosPrivate = useAxiosPrivate();
const { sessionDetails } = useSessionStore();
- const { details, defaultLlmProfile, updateCustomTool, llmProfiles } =
- useCustomToolStore();
+ const {
+ details,
+ defaultLlmProfile,
+ updateCustomTool,
+ llmProfiles,
+ isPublicSource,
+ } = useCustomToolStore();
const { setAlertDetails } = useAlertStore();
const handleException = useExceptionHandler();
const { setPostHogCustomEvent } = usePostHogEvents();
@@ -125,7 +130,11 @@ function ManageLlmProfiles() {
handleConfirm={() => handleDelete(item?.profile_id)}
content="The LLM profile will be permanently deleted."
>
-
-
+
Add New LLM Profile
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 69f517f75..0d053e4f3 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
@@ -6,7 +6,7 @@ import {
CloseCircleFilled,
InfoCircleFilled,
} from "@ant-design/icons";
-import { useNavigate } from "react-router-dom";
+import { useNavigate, useParams } from "react-router-dom";
import { useCustomToolStore } from "../../../store/custom-tool-store";
import { useSessionStore } from "../../../store/session-store";
@@ -24,6 +24,13 @@ import { useTokenUsageStore } from "../../../store/token-usage-store";
import TabPane from "antd/es/tabs/TabPane";
import { ProfileInfoBar } from "../profile-info-bar/ProfileInfoBar";
+let publicOutputsApi;
+try {
+ publicOutputsApi =
+ require("../../../plugins/prompt-studio-public-share/helpers/PublicShareAPIs").publicOutputsApi;
+} catch {
+ // The component will remain null of it is not available
+}
const columns = [
{
title: "Document",
@@ -72,11 +79,13 @@ function OutputForDocModal({
disableLlmOrDocChange,
singlePassExtractMode,
isSinglePassExtractLoading,
+ isPublicSource,
llmProfiles,
} = useCustomToolStore();
const { sessionDetails } = useSessionStore();
const axiosPrivate = useAxiosPrivate();
const navigate = useNavigate();
+ const { id } = useParams();
const { setAlertDetails } = useAlertStore();
const handleException = useExceptionHandler();
const { tokenUsage } = useTokenUsageStore();
@@ -180,14 +189,17 @@ function OutputForDocModal({
setRows([]);
return;
}
+ let url = `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/prompt-output/?tool_id=${details?.tool_id}&prompt_id=${promptId}&profile_manager=${profile}&is_single_pass_extract=${singlePassExtractMode}`;
+ if (isPublicSource) {
+ url = publicOutputsApi(id, promptId, profile, singlePassExtractMode);
+ }
const requestOptions = {
method: "GET",
- url: `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/prompt-output/?tool_id=${details?.tool_id}&prompt_id=${promptId}&profile_manager=${profile}&is_single_pass_extract=${singlePassExtractMode}`,
+ url,
headers: {
"X-CSRFToken": sessionDetails?.csrfToken,
},
};
-
setIsLoading(true);
axiosPrivate(requestOptions)
.then((res) => {
diff --git a/frontend/src/components/custom-tools/pre-and-post-amble-modal/PreAndPostAmbleModal.jsx b/frontend/src/components/custom-tools/pre-and-post-amble-modal/PreAndPostAmbleModal.jsx
index 036b95ddf..4e86c641a 100644
--- a/frontend/src/components/custom-tools/pre-and-post-amble-modal/PreAndPostAmbleModal.jsx
+++ b/frontend/src/components/custom-tools/pre-and-post-amble-modal/PreAndPostAmbleModal.jsx
@@ -18,7 +18,7 @@ const fieldNames = {
function PreAndPostAmbleModal({ type, handleUpdateTool }) {
const [title, setTitle] = useState("");
const [text, setText] = useState("");
- const { details, updateCustomTool } = useCustomToolStore();
+ const { details, updateCustomTool, isPublicSource } = useCustomToolStore();
const { setAlertDetails } = useAlertStore();
const handleException = useExceptionHandler();
@@ -93,13 +93,22 @@ function PreAndPostAmbleModal({ type, handleUpdateTool }) {
value={text}
onChange={(e) => setText(e.target.value)}
/>
-
+
Reset with default prompt
-
+
Save
diff --git a/frontend/src/components/custom-tools/prompt-card/Header.jsx b/frontend/src/components/custom-tools/prompt-card/Header.jsx
index 954b5706d..119576992 100644
--- a/frontend/src/components/custom-tools/prompt-card/Header.jsx
+++ b/frontend/src/components/custom-tools/prompt-card/Header.jsx
@@ -41,6 +41,7 @@ function Header({
singlePassExtractMode,
isSinglePassExtractLoading,
indexDocs,
+ isPublicSource,
} = useCustomToolStore();
const [isDisablePrompt, setIsDisablePrompt] = useState(promptDetails?.active);
@@ -130,7 +131,8 @@ function Header({
disabled={
disableLlmOrDocChange.includes(promptDetails?.prompt_id) ||
isSinglePassExtractLoading ||
- indexDocs.includes(selectedDoc?.document_id)
+ indexDocs.includes(selectedDoc?.document_id) ||
+ isPublicSource
}
>
@@ -151,7 +153,8 @@ function Header({
updateStatus?.status ===
promptStudioUpdateStatus?.isUpdating) ||
disableLlmOrDocChange?.includes(promptDetails?.prompt_id) ||
- indexDocs?.includes(selectedDoc?.document_id)
+ indexDocs?.includes(selectedDoc?.document_id) ||
+ isPublicSource
}
>
@@ -168,7 +171,8 @@ function Header({
updateStatus?.status ===
promptStudioUpdateStatus?.isUpdating) ||
disableLlmOrDocChange?.includes(promptDetails?.prompt_id) ||
- indexDocs?.includes(selectedDoc?.document_id)
+ indexDocs?.includes(selectedDoc?.document_id) ||
+ isPublicSource
}
>
@@ -180,6 +184,7 @@ function Header({
checked={isDisablePrompt}
className="prompt-card-action-button"
onChange={handleDisablePrompt}
+ disabled={isPublicSource}
/>
diff --git a/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx b/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx
index cb8313163..889a03d9f 100644
--- a/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx
+++ b/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx
@@ -18,6 +18,7 @@ import useTokenUsage from "../../../hooks/useTokenUsage";
import { useTokenUsageStore } from "../../../store/token-usage-store";
import { PromptCardItems } from "./PromptCardItems";
import "./PromptCard.css";
+import { useParams } from "react-router-dom";
const EvalModal = null;
const getEvalMetrics = (param1, param2) => {
@@ -34,7 +35,13 @@ try {
} catch {
// The component will remain null of it is not available
}
-
+let publicOutputsApi;
+try {
+ publicOutputsApi =
+ require("../../../plugins/prompt-studio-public-share/helpers/PublicShareAPIs").publicOutputsApi;
+} catch {
+ // The component will remain null of it is not available
+}
function PromptCard({
promptDetails,
handleChange,
@@ -69,6 +76,7 @@ function PromptCard({
singlePassExtractMode,
isSinglePassExtractLoading,
isSimplePromptStudio,
+ isPublicSource,
} = useCustomToolStore();
const { messages } = useSocketCustomToolStore();
const { sessionDetails } = useSessionStore();
@@ -78,6 +86,7 @@ function PromptCard({
const { setPostHogCustomEvent } = usePostHogEvents();
const { tokenUsage, setTokenUsage } = useTokenUsageStore();
const { getTokenUsage } = useTokenUsage();
+ const { id } = useParams();
useEffect(() => {
const outputTypeData = getDropdownItems("output_type") || {};
@@ -642,6 +651,14 @@ function PromptCard({
}
url = `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/prompt-output/?tool_id=${details?.tool_id}&prompt_id=${promptDetails?.prompt_id}&is_single_pass_extract=${singlePassExtractMode}`;
}
+ if (isPublicSource) {
+ url = publicOutputsApi(
+ id,
+ promptDetails?.prompt_id,
+ selectedLlmProfileId,
+ singlePassExtractMode
+ );
+ }
if (isOutput) {
url += `&document_manager=${selectedDoc?.document_id}`;
}
@@ -656,7 +673,6 @@ function PromptCard({
"X-CSRFToken": sessionDetails?.csrfToken,
},
};
-
return axiosPrivate(requestOptions)
.then((res) => {
const data = res?.data || [];
diff --git a/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx b/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx
index e6f800183..dbd2a472c 100644
--- a/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx
+++ b/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx
@@ -76,6 +76,7 @@ function PromptCardItems({
isSinglePassExtractLoading,
indexDocs,
isSimplePromptStudio,
+ isPublicSource,
adapters,
} = useCustomToolStore();
const [isEditingPrompt, setIsEditingPrompt] = useState(false);
@@ -301,6 +302,7 @@ function PromptCardItems({
type="link"
className="display-flex-align-center prompt-card-action-button"
onClick={() => setOpenOutputForDoc(true)}
+ disabled={isPublicSource}
>
{isCoverageLoading ? (
@@ -331,7 +333,8 @@ function PromptCardItems({
promptDetails?.prompt_id
) ||
isSinglePassExtractLoading ||
- indexDocs.includes(selectedDoc?.document_id)
+ indexDocs.includes(selectedDoc?.document_id) ||
+ isPublicSource
}
onChange={(value) => handleTypeChange(value)}
/>
@@ -412,6 +415,7 @@ function PromptCardItems({
onChange={(checked) =>
handleTagChange(checked, profileId)
}
+ disabled={isPublicSource}
className={isChecked ? "checked" : "unchecked"}
>
{isChecked ? (
@@ -456,6 +460,7 @@ function PromptCardItems({
onChange={() =>
handleSelectDefaultLLM(profileId)
}
+ disabled={isPublicSource}
>
Default
@@ -504,7 +509,7 @@ function PromptCardItems({
disabled={
isRunLoading[
`${selectedDoc?.document_id}_${profileId}`
- ]
+ ] || isPublicSource
}
>
@@ -519,7 +524,7 @@ function PromptCardItems({
disabled={
isRunLoading[
`${selectedDoc?.document_id}_${profileId}`
- ]
+ ] || isPublicSource
}
>
diff --git a/frontend/src/components/custom-tools/tool-ide/ToolIde.jsx b/frontend/src/components/custom-tools/tool-ide/ToolIde.jsx
index 7ade1571c..0dfaae6fd 100644
--- a/frontend/src/components/custom-tools/tool-ide/ToolIde.jsx
+++ b/frontend/src/components/custom-tools/tool-ide/ToolIde.jsx
@@ -1,6 +1,6 @@
import { FullscreenExitOutlined, FullscreenOutlined } from "@ant-design/icons";
import { Col, Collapse, Modal, Row } from "antd";
-import { useState } from "react";
+import { useState, useEffect } from "react";
import { useAxiosPrivate } from "../../../hooks/useAxiosPrivate";
import { useExceptionHandler } from "../../../hooks/useExceptionHandler";
@@ -16,8 +16,11 @@ import { SettingsModal } from "../settings-modal/SettingsModal";
import { ToolsMain } from "../tools-main/ToolsMain";
import "./ToolIde.css";
import usePostHogEvents from "../../../hooks/usePostHogEvents.js";
-
let OnboardMessagesModal;
+let PromptShareModal;
+let PromptShareLink;
+let CloneTitle;
+let HeaderPublic;
let slides;
try {
OnboardMessagesModal =
@@ -28,6 +31,18 @@ try {
OnboardMessagesModal = null;
slides = [];
}
+try {
+ PromptShareModal =
+ require("../../../plugins/prompt-studio-public-share/public-share-modal/PromptShareModal.jsx").PromptShareModal;
+ PromptShareLink =
+ require("../../../plugins/prompt-studio-public-share/public-link-modal/PromptShareLink.jsx").PromptShareLink;
+ CloneTitle =
+ require("../../../plugins/prompt-studio-clone/clone-title-modal/CloneTitle.jsx").CloneTitle;
+ HeaderPublic =
+ require("../../../plugins/prompt-studio-public-share/header-public/HeaderPublic.jsx").HeaderPublic;
+} catch (err) {
+ // Do nothing if plugins are not loaded.
+}
function ToolIde() {
const [showLogsModal, setShowLogsModal] = useState(false);
@@ -42,6 +57,8 @@ function ToolIde() {
indexDocs,
pushIndexDoc,
deleteIndexDoc,
+ shareId,
+ isPublicSource,
} = useCustomToolStore();
const { sessionDetails } = useSessionStore();
const { promptOnboardingMessage } = sessionDetails;
@@ -50,6 +67,10 @@ function ToolIde() {
const handleException = useExceptionHandler();
const [loginModalOpen, setLoginModalOpen] = useState(true);
const { setPostHogCustomEvent } = usePostHogEvents();
+ const [openShareLink, setOpenShareLink] = useState(false);
+ const [openShareConfirmation, setOpenShareConfirmation] = useState(false);
+ const [openShareModal, setOpenShareModal] = useState(false);
+ const [openCloneModal, setOpenCloneModal] = useState(false);
const openLogsModal = () => {
setShowLogsModal(true);
@@ -58,6 +79,17 @@ function ToolIde() {
const closeLogsModal = () => {
setShowLogsModal(false);
};
+ useEffect(() => {
+ if (openShareModal) {
+ if (shareId) {
+ setOpenShareConfirmation(false);
+ setOpenShareLink(true);
+ } else {
+ setOpenShareConfirmation(true);
+ setOpenShareLink(false);
+ }
+ }
+ }, [shareId, openShareModal]);
const genExtra = () => (
+ {isPublicSource && HeaderPublic && }
@@ -244,6 +279,26 @@ function ToolIde() {
setOpen={setOpenSettings}
handleUpdateTool={handleUpdateTool}
/>
+ {PromptShareModal && (
+
+ )}
+ {PromptShareLink && (
+
+ )}
+ {CloneTitle && (
+
+ )}
{!promptOnboardingMessage && OnboardMessagesModal && (
{
const data = res?.data;
updatedCusTool["llmProfiles"] = data;
+ const reqOpsShare = {
+ method: "GET",
+ url: `/api/v1/unstract/${sessionDetails?.orgId}/share-manager/tool-source/?tool_id=${id}`,
+ };
+ return handleApiRequest(reqOpsShare);
+ })
+ .then((res) => {
+ const data = res?.data;
+ updatedCusTool["shareId"] = data?.share_id;
const reqOpsLlmProfiles = {
method: "GET",
url: `/api/v1/unstract/${sessionDetails?.orgId}/adapter/`,
diff --git a/frontend/src/routes/Router.jsx b/frontend/src/routes/Router.jsx
index d564714c0..291c39ec0 100644
--- a/frontend/src/routes/Router.jsx
+++ b/frontend/src/routes/Router.jsx
@@ -37,6 +37,8 @@ let ChatAppPage;
let ChatAppLayout;
let ManualReviewPage;
let ReviewLayout;
+let PublicPromptStudioHelper;
+
try {
TrialRoutes =
require("../plugins/subscription/trial-page/TrialEndPage.jsx").TrialEndPage;
@@ -84,7 +86,12 @@ try {
} catch (err) {
// Do nothing, Not-found Page will be triggered.
}
-
+try {
+ PublicPromptStudioHelper =
+ require("../plugins/prompt-studio-public-share/helpers/PublicPromptStudioHelper.js").PublicPromptStudioHelper;
+} catch (err) {
+ // Do nothing, Not-found Page will be triggered.
+}
function Router() {
return (
@@ -111,6 +118,18 @@ function Router() {
} />
)}
+ {PublicPromptStudioHelper && (
+ }
+ >
+ } />
+ }
+ />
+
+ )}
{/* protected routes */}
diff --git a/frontend/src/store/custom-tool-store.js b/frontend/src/store/custom-tool-store.js
index ba3019fa4..452989545 100644
--- a/frontend/src/store/custom-tool-store.js
+++ b/frontend/src/store/custom-tool-store.js
@@ -16,6 +16,8 @@ const defaultState = {
singlePassExtractMode: false,
isSinglePassExtractLoading: false,
isSimplePromptStudio: false,
+ shareId: null,
+ isPublicSource: false,
adapters: [],
};
diff --git a/unstract/connectors/src/unstract/connectors/filesystems/__init__.py b/unstract/connectors/src/unstract/connectors/filesystems/__init__.py
index 4826bdb25..7635b7ca1 100644
--- a/unstract/connectors/src/unstract/connectors/filesystems/__init__.py
+++ b/unstract/connectors/src/unstract/connectors/filesystems/__init__.py
@@ -1,5 +1,7 @@
from unstract.connectors import ConnectorDict # type: ignore
from unstract.connectors.filesystems.register import register_connectors
+from .local_storage.local_storage import * # noqa: F401, F403
+
connectors: ConnectorDict = {}
register_connectors(connectors)