From 40fd8360d09b9d445e1eb1146f75005295f1ffa4 Mon Sep 17 00:00:00 2001 From: Chandrasekharan M Date: Fri, 20 Sep 2024 13:34:57 +0530 Subject: [PATCH 1/3] multi-tenant v2 PS changes from PR 611 --- .../prompt_studio_core_v2/exceptions.py | 19 ++++ .../prompt_variable_service.py | 93 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py diff --git a/backend/prompt_studio/prompt_studio_core_v2/exceptions.py b/backend/prompt_studio/prompt_studio_core_v2/exceptions.py index a58f672d2..273d6eabe 100644 --- a/backend/prompt_studio/prompt_studio_core_v2/exceptions.py +++ b/backend/prompt_studio/prompt_studio_core_v2/exceptions.py @@ -67,3 +67,22 @@ class MaxProfilesReachedError(APIException): f"Maximum number of profiles (max {ProfileManagerKeys.MAX_PROFILE_COUNT})" " per prompt studio project has been reached." ) + + +class OperationNotSupported(APIException): + status_code = 403 + default_detail = ( + "This feature is not supported " + "in the open-source version. " + "Please check our cloud or enterprise on-premise offering " + "for access to this functionality." + ) + + +class PromptNotRun(APIException): + status_code = 403 + default_detail = ( + "The prompt must be executed before " + "it can be used as a variable in another prompt. " + "Please execute the prompt first and try again." + ) diff --git a/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py b/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py new file mode 100644 index 000000000..d098c01fb --- /dev/null +++ b/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py @@ -0,0 +1,93 @@ +import re +from enum import Enum +from typing import Any + +from prompt_studio.prompt_studio.models import ToolStudioPrompt +from prompt_studio.prompt_studio_core.exceptions import PromptNotRun +from prompt_studio.prompt_studio_output_manager.models import PromptStudioOutputManager + + +class VariableType(str, Enum): + STATIC = "STATIC" + DYNAMIC = "DYNAMIC" + + +class VariableConstants: + + VARIABLE_REGEX = "{{(.+?)}}" + DYNAMIC_VARIABLE_DATA_REGEX = r"\[(.*?)\]" + DYNAMIC_VARIABLE_URL_REGEX = r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))" # noqa: E501 + + +class PromptStudioVariableService: + + @staticmethod + def fetch_variable_outputs(variable: str, doc_id: str, tool_id: str) -> Any: + variable_prompt: ToolStudioPrompt = ToolStudioPrompt.objects.get( + prompt_key=variable, tool_id=tool_id + ) + try: + output = PromptStudioOutputManager.objects.get( + prompt_id=variable_prompt.prompt_id, + document_manager=doc_id, + tool_id=variable_prompt.tool_id, + profile_manager=variable_prompt.profile_manager, + is_single_pass_extract=False, + ) + except PromptStudioOutputManager.DoesNotExist: + raise PromptNotRun( + f"The prompt : {variable} must be executed before " + "it can be used as a variable in another prompt. " + "Please execute the prompt first and try again." + ) + return output.output + + @staticmethod + def identify_variable_type(variable: str) -> VariableType: + variable_type: VariableType + pattern = re.compile(VariableConstants.DYNAMIC_VARIABLE_URL_REGEX) + if re.findall(pattern, variable): + variable_type = VariableType.DYNAMIC + else: + variable_type = VariableType.STATIC + return variable_type + + @staticmethod + def extract_variables_from_prompt(prompt: str) -> list[str]: + variable: list[str] = [] + variable = re.findall(VariableConstants.VARIABLE_REGEX, prompt) + return variable + + @staticmethod + def frame_variable_replacement_map( + doc_id: str, prompt_object: ToolStudioPrompt + ) -> dict[str, Any]: + variable_output_map: dict[str, Any] = {} + prompt = prompt_object.prompt + variables = PromptStudioVariableService.extract_variables_from_prompt( + prompt=prompt + ) + for variable in variables: + variable_type: VariableType = ( + PromptStudioVariableService.identify_variable_type(variable=variable) + ) + if variable_type == VariableType.STATIC: + variable_output_map[variable] = ( + PromptStudioVariableService.fetch_variable_outputs( + variable=variable, + doc_id=doc_id, + tool_id=prompt_object.tool_id.tool_id, + ) + ) + if variable_type == VariableType.DYNAMIC: + variable = re.findall( + VariableConstants.DYNAMIC_VARIABLE_DATA_REGEX, variable + )[0] + variable_output_map[variable] = ( + PromptStudioVariableService.fetch_variable_outputs( + variable=variable, + doc_id=doc_id, + tool_id=prompt_object.tool_id.tool_id, + ) + ) + return variable_output_map From 9f9991edce91804a474fadf9ccd5057e1bca3fe1 Mon Sep 17 00:00:00 2001 From: Chandrasekharan M Date: Tue, 24 Sep 2024 13:07:06 +0530 Subject: [PATCH 2/3] Updated to v2 import --- .../prompt_studio_core_v2/prompt_variable_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py b/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py index d098c01fb..b90ab6ef7 100644 --- a/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py +++ b/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py @@ -2,9 +2,9 @@ from enum import Enum from typing import Any -from prompt_studio.prompt_studio.models import ToolStudioPrompt -from prompt_studio.prompt_studio_core.exceptions import PromptNotRun +from prompt_studio.prompt_studio_core_v2.exceptions import PromptNotRun from prompt_studio.prompt_studio_output_manager.models import PromptStudioOutputManager +from prompt_studio.prompt_studio_v2.models import ToolStudioPrompt class VariableType(str, Enum): From 2240d9380d6e5f0594c9165d9d7f718a9da39f5d Mon Sep 17 00:00:00 2001 From: ali-zipstack Date: Wed, 25 Sep 2024 12:06:58 +0530 Subject: [PATCH 3/3] resolved import issue --- .../prompt_studio_core_v2/prompt_variable_service.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py b/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py index b90ab6ef7..f55108bd2 100644 --- a/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py +++ b/backend/prompt_studio/prompt_studio_core_v2/prompt_variable_service.py @@ -3,7 +3,9 @@ from typing import Any from prompt_studio.prompt_studio_core_v2.exceptions import PromptNotRun -from prompt_studio.prompt_studio_output_manager.models import PromptStudioOutputManager +from prompt_studio.prompt_studio_output_manager_v2.models import ( + PromptStudioOutputManager, +) from prompt_studio.prompt_studio_v2.models import ToolStudioPrompt