From 7b9555061b9b3e363dafc2a5ee7ffc96a184ef5f Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Wed, 11 Dec 2024 12:01:12 +0530 Subject: [PATCH 01/15] added required field in prompt key --- .../0003_toolstudioprompt_required.py | 18 ++++++++++++++++++ .../prompt_studio/prompt_studio_v2/models.py | 1 + 2 files changed, 19 insertions(+) create mode 100644 backend/prompt_studio/prompt_studio_v2/migrations/0003_toolstudioprompt_required.py diff --git a/backend/prompt_studio/prompt_studio_v2/migrations/0003_toolstudioprompt_required.py b/backend/prompt_studio/prompt_studio_v2/migrations/0003_toolstudioprompt_required.py new file mode 100644 index 000000000..69a1d0eaf --- /dev/null +++ b/backend/prompt_studio/prompt_studio_v2/migrations/0003_toolstudioprompt_required.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.1 on 2024-12-10 10:07 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("prompt_studio_v2", "0002_alter_toolstudioprompt_enforce_type"), + ] + + operations = [ + migrations.AddField( + model_name="toolstudioprompt", + name="required", + field=models.BooleanField(default=False), + ), + ] diff --git a/backend/prompt_studio/prompt_studio_v2/models.py b/backend/prompt_studio/prompt_studio_v2/models.py index 9cd37c36f..3905a95e3 100644 --- a/backend/prompt_studio/prompt_studio_v2/models.py +++ b/backend/prompt_studio/prompt_studio_v2/models.py @@ -84,6 +84,7 @@ class Mode(models.TextChoices): db_comment="Field to store the prompt key", unique=False, ) + required = models.BooleanField(default=False) is_assert = models.BooleanField(default=False) active = models.BooleanField(default=True, null=False, blank=False) output_metadata = models.JSONField( From 43dbed339f25413eeef80fa5758ccde8d201d30d Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Wed, 11 Dec 2024 12:02:20 +0530 Subject: [PATCH 02/15] required fields constant and added required field in promptstudio helper --- backend/prompt_studio/prompt_studio_core_v2/constants.py | 1 + .../prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/prompt_studio/prompt_studio_core_v2/constants.py b/backend/prompt_studio/prompt_studio_core_v2/constants.py index cb335b90f..f5f27f3f1 100644 --- a/backend/prompt_studio/prompt_studio_core_v2/constants.py +++ b/backend/prompt_studio/prompt_studio_core_v2/constants.py @@ -96,6 +96,7 @@ class ToolStudioPromptKeys: RECORD = "record" FILE_PATH = "file_path" ENABLE_HIGHLIGHT = "enable_highlight" + REQUIRED = "required" class FileViewTypes: diff --git a/backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py b/backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py index 75a7f3f4f..a0b97bf91 100644 --- a/backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py +++ b/backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py @@ -815,6 +815,7 @@ def _fetch_response( output[TSPKeys.PROMPT] = prompt.prompt output[TSPKeys.ACTIVE] = prompt.active + output[TSPKeys.REQUIRED] = prompt.required output[TSPKeys.CHUNK_SIZE] = profile_manager.chunk_size output[TSPKeys.VECTOR_DB] = vector_db output[TSPKeys.EMBEDDING] = embedding_model From 997d310cf23093dadc773376845d14a65bbd4289 Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Wed, 11 Dec 2024 12:02:53 +0530 Subject: [PATCH 03/15] added frontend required field prompt key functionality --- .../custom-tools/prompt-card/Header.jsx | 21 ++++++++++++++++++- .../custom-tools/prompt-card/PromptCard.jsx | 1 - 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/custom-tools/prompt-card/Header.jsx b/frontend/src/components/custom-tools/prompt-card/Header.jsx index f72a36083..f5fa8bd4c 100644 --- a/frontend/src/components/custom-tools/prompt-card/Header.jsx +++ b/frontend/src/components/custom-tools/prompt-card/Header.jsx @@ -58,6 +58,7 @@ function Header({ const [items, setItems] = useState([]); const [isDisablePrompt, setIsDisablePrompt] = useState(null); + const [isRequired, setIsRequired] = useState(false); const handleRunBtnClick = (promptRunType, docId = null) => { setExpandCard(true); @@ -73,8 +74,18 @@ function Header({ } ); }; + const handleRequired = (event) => { + const check = event?.target?.checked; + setIsRequired(check); + handleChange(check, promptDetails?.prompt_id, "required", true, true).catch( + () => { + setIsRequired(!check); + } + ); + }; useEffect(() => { setIsDisablePrompt(promptDetails?.active); + setIsRequired(promptDetails?.required); }, [promptDetails, details]); useEffect(() => { @@ -87,6 +98,14 @@ function Header({ ), key: "enable", }, + { + label: ( + + Required + + ), + key: "required", + }, { label: ( diff --git a/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx b/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx index 1cda03555..cbee89bee 100644 --- a/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx +++ b/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx @@ -112,7 +112,6 @@ const PromptCard = memo( name = event.target.name; value = event.target.value; } - const prevPromptDetailsState = { ...promptDetailsState }; const updatedPromptDetailsState = { ...promptDetailsState }; From 53fb46651af24a588bfd300b776e658899886b8a Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Wed, 11 Dec 2024 12:04:05 +0530 Subject: [PATCH 04/15] added prompt service required key adding in metadata --- .../src/unstract/prompt_service/constants.py | 2 ++ .../src/unstract/prompt_service/helper.py | 24 +++++++++++++++++-- .../src/unstract/prompt_service/main.py | 8 ++++++- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/prompt-service/src/unstract/prompt_service/constants.py b/prompt-service/src/unstract/prompt_service/constants.py index a654ce5c2..e5ba3e67f 100644 --- a/prompt-service/src/unstract/prompt_service/constants.py +++ b/prompt-service/src/unstract/prompt_service/constants.py @@ -72,6 +72,8 @@ class PromptServiceContants: FILE_PATH = "file_path" HIGHLIGHT_DATA = "highlight_data" CONFIDENCE_DATA = "confidence_data" + REQUIRED_FIELDS = "required_fields" + REQUIRED = "required" class RunLevel(Enum): diff --git a/prompt-service/src/unstract/prompt_service/helper.py b/prompt-service/src/unstract/prompt_service/helper.py index 62a24f2d1..7393b03af 100644 --- a/prompt-service/src/unstract/prompt_service/helper.py +++ b/prompt-service/src/unstract/prompt_service/helper.py @@ -297,7 +297,7 @@ def run_completion( answer: str = completion[PSKeys.RESPONSE].text highlight_data = completion.get(PSKeys.HIGHLIGHT_DATA) confidence_data = completion.get(PSKeys.CONFIDENCE_DATA) - + required_fields = True if metadata is not None and prompt_key: if highlight_data: metadata.setdefault(PSKeys.HIGHLIGHT_DATA, {})[ @@ -308,7 +308,9 @@ def run_completion( metadata.setdefault(PSKeys.CONFIDENCE_DATA, {})[ prompt_key ] = confidence_data - + metadata.setdefault(PSKeys.REQUIRED_FIELDS, {})[ + prompt_key + ] = required_fields return answer # TODO: Catch and handle specific exception here except SdkRateLimitError as e: @@ -344,3 +346,21 @@ def extract_table( except table_extractor["exception_cls"] as e: msg = f"Couldn't extract table. {e}" raise APIError(message=msg) + + +def add_required_field( + required_fields: list[str], key: str, required: bool +) -> list[str]: + """ + Retrieve a list of required prompt keys for a specific tool ID. + + Args: + tool_id (str): The ID of the tool for which required fields are retrieved. + + Returns: + List[str]: A list of prompt keys marked as required for the given tool ID. + """ + if required: + required_fields.append(key) + + return required_fields diff --git a/prompt-service/src/unstract/prompt_service/main.py b/prompt-service/src/unstract/prompt_service/main.py index 12c2242e0..18a0d0c16 100644 --- a/prompt-service/src/unstract/prompt_service/main.py +++ b/prompt-service/src/unstract/prompt_service/main.py @@ -11,6 +11,7 @@ from unstract.prompt_service.constants import RunLevel from unstract.prompt_service.exceptions import APIError, ErrorResponse, NoPayloadError from unstract.prompt_service.helper import ( + add_required_field, construct_and_run_prompt, extract_table, extract_variable, @@ -108,6 +109,7 @@ def prompt_processor() -> Any: PSKeys.RUN_ID: run_id, PSKeys.FILE_NAME: doc_name, PSKeys.CONTEXT: {}, + PSKeys.REQUIRED_FIELDS: [], } variable_names: list[str] = [] publish_log( @@ -117,10 +119,14 @@ def prompt_processor() -> Any: RunLevel.RUN, f"Preparing to execute {len(prompts)} prompt(s)", ) - # TODO: Rename "output" to "prompt" for output in prompts: # type:ignore variable_names.append(output[PSKeys.NAME]) + metadata[PSKeys.REQUIRED_FIELDS] = add_required_field( + metadata[PSKeys.REQUIRED_FIELDS], + output[PSKeys.NAME], + output.get(PSKeys.REQUIRED, False), + ) for output in prompts: # type:ignore prompt_name = output[PSKeys.NAME] prompt_text = output[PSKeys.PROMPT] From 0c97509fc39f4b4f7547cf997aef5e568addbc17 Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Wed, 11 Dec 2024 16:23:22 +0530 Subject: [PATCH 05/15] added required key in prompt studio registry and removed some unwanted codes --- backend/prompt_studio/prompt_studio_registry_v2/constants.py | 1 + .../prompt_studio_registry_helper.py | 1 + prompt-service/src/unstract/prompt_service/helper.py | 5 ----- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/backend/prompt_studio/prompt_studio_registry_v2/constants.py b/backend/prompt_studio/prompt_studio_registry_v2/constants.py index ab00a9f2d..49bc1de04 100644 --- a/backend/prompt_studio/prompt_studio_registry_v2/constants.py +++ b/backend/prompt_studio/prompt_studio_registry_v2/constants.py @@ -98,6 +98,7 @@ class JsonSchemaKey: SUMMARIZE_AS_SOURCE = "summarize_as_source" ENABLE_HIGHLIGHT = "enable_highlight" PLATFORM_POSTAMBLE = "platform_postamble" + REQUIRED = "required" class SpecKey: diff --git a/backend/prompt_studio/prompt_studio_registry_v2/prompt_studio_registry_helper.py b/backend/prompt_studio/prompt_studio_registry_v2/prompt_studio_registry_helper.py index 157593cdd..8590c1b03 100644 --- a/backend/prompt_studio/prompt_studio_registry_v2/prompt_studio_registry_helper.py +++ b/backend/prompt_studio/prompt_studio_registry_v2/prompt_studio_registry_helper.py @@ -322,6 +322,7 @@ def frame_export_json( output[JsonSchemaKey.PROMPT] = prompt.prompt output[JsonSchemaKey.ACTIVE] = prompt.active + output[JsonSchemaKey.REQUIRED] = prompt.required output[JsonSchemaKey.CHUNK_SIZE] = prompt.profile_manager.chunk_size output[JsonSchemaKey.VECTOR_DB] = vector_db output[JsonSchemaKey.EMBEDDING] = embedding_model diff --git a/prompt-service/src/unstract/prompt_service/helper.py b/prompt-service/src/unstract/prompt_service/helper.py index 7393b03af..ec4ffa621 100644 --- a/prompt-service/src/unstract/prompt_service/helper.py +++ b/prompt-service/src/unstract/prompt_service/helper.py @@ -297,7 +297,6 @@ def run_completion( answer: str = completion[PSKeys.RESPONSE].text highlight_data = completion.get(PSKeys.HIGHLIGHT_DATA) confidence_data = completion.get(PSKeys.CONFIDENCE_DATA) - required_fields = True if metadata is not None and prompt_key: if highlight_data: metadata.setdefault(PSKeys.HIGHLIGHT_DATA, {})[ @@ -308,9 +307,6 @@ def run_completion( metadata.setdefault(PSKeys.CONFIDENCE_DATA, {})[ prompt_key ] = confidence_data - metadata.setdefault(PSKeys.REQUIRED_FIELDS, {})[ - prompt_key - ] = required_fields return answer # TODO: Catch and handle specific exception here except SdkRateLimitError as e: @@ -362,5 +358,4 @@ def add_required_field( """ if required: required_fields.append(key) - return required_fields From 4781f5ffd99b395e37e1eaa1db1be2cd85f47492 Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Thu, 12 Dec 2024 15:31:27 +0530 Subject: [PATCH 06/15] changed required field bool to option with any/all --- .../0004_alter_toolstudioprompt_required.py | 24 +++++++++++++++++++ .../prompt_studio/prompt_studio_v2/models.py | 12 +++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 backend/prompt_studio/prompt_studio_v2/migrations/0004_alter_toolstudioprompt_required.py diff --git a/backend/prompt_studio/prompt_studio_v2/migrations/0004_alter_toolstudioprompt_required.py b/backend/prompt_studio/prompt_studio_v2/migrations/0004_alter_toolstudioprompt_required.py new file mode 100644 index 000000000..58dba3d26 --- /dev/null +++ b/backend/prompt_studio/prompt_studio_v2/migrations/0004_alter_toolstudioprompt_required.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.1 on 2024-12-12 08:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("prompt_studio_v2", "0003_toolstudioprompt_required"), + ] + + operations = [ + migrations.AlterField( + model_name="toolstudioprompt", + name="required", + field=models.CharField( + blank=True, + choices=[("all", "All values required"), ("any", "Any value required")], + default=None, + max_length=3, + null=True, + ), + ), + ] diff --git a/backend/prompt_studio/prompt_studio_v2/models.py b/backend/prompt_studio/prompt_studio_v2/models.py index 3905a95e3..1aab89eeb 100644 --- a/backend/prompt_studio/prompt_studio_v2/models.py +++ b/backend/prompt_studio/prompt_studio_v2/models.py @@ -84,7 +84,17 @@ class Mode(models.TextChoices): db_comment="Field to store the prompt key", unique=False, ) - required = models.BooleanField(default=False) + REQUIRED_CHOICES = [ + ("all", "All values required"), + ("any", "Any value required"), + ] + required = models.CharField( + max_length=3, + choices=REQUIRED_CHOICES, + null=True, # Allows the field to store NULL in the database + blank=True, # Allows the field to be optional in forms + default=None, # Sets the default value to None + ) is_assert = models.BooleanField(default=False) active = models.BooleanField(default=True, null=False, blank=False) output_metadata = models.JSONField( From fd295933e33a413ea8323a0e5ce6607224382a20 Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Thu, 12 Dec 2024 15:32:17 +0530 Subject: [PATCH 07/15] made changes in frontend to support option required --- .../custom-tools/prompt-card/Header.jsx | 43 +++++++++++++------ .../custom-tools/prompt-card/PromptCard.jsx | 1 + 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/frontend/src/components/custom-tools/prompt-card/Header.jsx b/frontend/src/components/custom-tools/prompt-card/Header.jsx index f5fa8bd4c..cc7b14a33 100644 --- a/frontend/src/components/custom-tools/prompt-card/Header.jsx +++ b/frontend/src/components/custom-tools/prompt-card/Header.jsx @@ -58,7 +58,7 @@ function Header({ const [items, setItems] = useState([]); const [isDisablePrompt, setIsDisablePrompt] = useState(null); - const [isRequired, setIsRequired] = useState(false); + const [required, setRequired] = useState(false); const handleRunBtnClick = (promptRunType, docId = null) => { setExpandCard(true); @@ -74,18 +74,22 @@ function Header({ } ); }; - const handleRequired = (event) => { - const check = event?.target?.checked; - setIsRequired(check); - handleChange(check, promptDetails?.prompt_id, "required", true, true).catch( - () => { - setIsRequired(!check); - } - ); + const handleRequiredChange = (value) => { + const newValue = value === required ? null : value; // Allow deselection + setRequired(newValue); + handleChange( + newValue, + promptDetails?.prompt_id, + "required", + true, + true + ).catch(() => { + setRequired(promptDetails?.required || null); // Rollback state in case of error + }); }; useEffect(() => { setIsDisablePrompt(promptDetails?.active); - setIsRequired(promptDetails?.required); + setRequired(promptDetails?.required); }, [promptDetails, details]); useEffect(() => { @@ -100,9 +104,20 @@ function Header({ }, { label: ( - - Required - +
+ handleRequiredChange("all")} + > + All Required + + handleRequiredChange("any")} + > + Any Required + +
), key: "required", }, @@ -128,7 +143,7 @@ function Header({ } setItems(dropdownItems); - }, [isDisablePrompt, isRequired]); + }, [isDisablePrompt, required]); return ( diff --git a/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx b/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx index cbee89bee..1cda03555 100644 --- a/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx +++ b/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx @@ -112,6 +112,7 @@ const PromptCard = memo( name = event.target.name; value = event.target.value; } + const prevPromptDetailsState = { ...promptDetailsState }; const updatedPromptDetailsState = { ...promptDetailsState }; From 0dcf64a57bea0378595ae7f9ac8d539d854e86d6 Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Thu, 12 Dec 2024 15:34:06 +0530 Subject: [PATCH 08/15] prompt service changes to support required options field --- .../src/unstract/prompt_service/helper.py | 18 +++++++++++------- .../src/unstract/prompt_service/main.py | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/prompt-service/src/unstract/prompt_service/helper.py b/prompt-service/src/unstract/prompt_service/helper.py index ec4ffa621..64307af41 100644 --- a/prompt-service/src/unstract/prompt_service/helper.py +++ b/prompt-service/src/unstract/prompt_service/helper.py @@ -345,17 +345,21 @@ def extract_table( def add_required_field( - required_fields: list[str], key: str, required: bool -) -> list[str]: + required_fields: dict[str, str], key: str, required: str +) -> dict[str, str]: """ - Retrieve a list of required prompt keys for a specific tool ID. + Add or update a required field in the required_fields dictionary. Args: - tool_id (str): The ID of the tool for which required fields are retrieved. + required_fields (Dict[str, str]): The dictionary + containing existing required fields, + where keys are field names and values are boolean flags. + key (str): The field key to add or update in the dictionary. + required (str): A indicating whether the + all/any values in field is required. Returns: - List[str]: A list of prompt keys marked as required for the given tool ID. + Dict[str, str]: The updated dictionary of required fields. """ - if required: - required_fields.append(key) + required_fields[key] = required return required_fields diff --git a/prompt-service/src/unstract/prompt_service/main.py b/prompt-service/src/unstract/prompt_service/main.py index 18a0d0c16..c5fb0d279 100644 --- a/prompt-service/src/unstract/prompt_service/main.py +++ b/prompt-service/src/unstract/prompt_service/main.py @@ -109,7 +109,7 @@ def prompt_processor() -> Any: PSKeys.RUN_ID: run_id, PSKeys.FILE_NAME: doc_name, PSKeys.CONTEXT: {}, - PSKeys.REQUIRED_FIELDS: [], + PSKeys.REQUIRED_FIELDS: {}, } variable_names: list[str] = [] publish_log( @@ -125,7 +125,7 @@ def prompt_processor() -> Any: metadata[PSKeys.REQUIRED_FIELDS] = add_required_field( metadata[PSKeys.REQUIRED_FIELDS], output[PSKeys.NAME], - output.get(PSKeys.REQUIRED, False), + output.get(PSKeys.REQUIRED, None), ) for output in prompts: # type:ignore prompt_name = output[PSKeys.NAME] From d70c55d25c7a1400d225e01981b2902ab1cd044b Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Mon, 16 Dec 2024 15:48:22 +0530 Subject: [PATCH 09/15] required field based on enforce type --- .../custom-tools/prompt-card/Header.jsx | 40 +++++++++++++------ .../prompt-card/PromptCardItems.jsx | 1 + 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/frontend/src/components/custom-tools/prompt-card/Header.jsx b/frontend/src/components/custom-tools/prompt-card/Header.jsx index cc7b14a33..28f90aa31 100644 --- a/frontend/src/components/custom-tools/prompt-card/Header.jsx +++ b/frontend/src/components/custom-tools/prompt-card/Header.jsx @@ -45,6 +45,7 @@ function Header({ setExpandCard, spsLoading, handleSpsLoading, + enforceType, }) { const { selectedDoc, @@ -105,18 +106,30 @@ function Header({ { label: (
- handleRequiredChange("all")} - > - All Required - - handleRequiredChange("any")} - > - Any Required - + {["json", "table", "record"].indexOf(enforceType) === -1 && ( + handleRequiredChange("all")} + > + Required + + )} + {enforceType === "json" && ( + <> + handleRequiredChange("all")} + > + All Required + + handleRequiredChange("any")} + > + Any Required + + + )}
), key: "required", @@ -143,7 +156,7 @@ function Header({ } setItems(dropdownItems); - }, [isDisablePrompt, required]); + }, [isDisablePrompt, required, enforceType]); return ( @@ -304,6 +317,7 @@ Header.propTypes = { setExpandCard: PropTypes.func.isRequired, spsLoading: PropTypes.object, handleSpsLoading: PropTypes.func.isRequired, + enforceType: PropTypes.text, }; export { Header }; diff --git a/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx b/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx index 0e50ff9d0..fd06b23b5 100644 --- a/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx +++ b/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx @@ -169,6 +169,7 @@ function PromptCardItems({ enabledProfiles={enabledProfiles} spsLoading={spsLoading} handleSpsLoading={handleSpsLoading} + enforceType={enforceType} /> From 871c67df607b7bb742e5f70b00e0020dedf8eadb Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Tue, 17 Dec 2024 11:41:12 +0530 Subject: [PATCH 10/15] changed required choices to class --- backend/prompt_studio/prompt_studio_v2/models.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/backend/prompt_studio/prompt_studio_v2/models.py b/backend/prompt_studio/prompt_studio_v2/models.py index 1aab89eeb..d520d4958 100644 --- a/backend/prompt_studio/prompt_studio_v2/models.py +++ b/backend/prompt_studio/prompt_studio_v2/models.py @@ -35,7 +35,15 @@ class PromptType(models.TextChoices): class Mode(models.TextChoices): DEFAULT = "Default", "Default choice for output" - prompt_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + class RequiredType(models.TextChoices): + ALL = "all", "All values required" + ANY = "any", "Any value required" + + prompt_id = models.UUIDField( + primary_key=True, + default=uuid.uuid4, + editable=False, + ) prompt_key = models.TextField( blank=False, db_comment="Field to store the prompt key", @@ -84,13 +92,9 @@ class Mode(models.TextChoices): db_comment="Field to store the prompt key", unique=False, ) - REQUIRED_CHOICES = [ - ("all", "All values required"), - ("any", "Any value required"), - ] required = models.CharField( max_length=3, - choices=REQUIRED_CHOICES, + choices=RequiredType.choices, null=True, # Allows the field to store NULL in the database blank=True, # Allows the field to be optional in forms default=None, # Sets the default value to None From 7e7f6662b8aad40ba3e10424a17d2fcf1e3d8e14 Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Tue, 17 Dec 2024 12:01:50 +0530 Subject: [PATCH 11/15] frontend condition fail issue fix in highlight data --- frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx b/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx index 765e468b7..3b2e321ca 100644 --- a/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx +++ b/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx @@ -36,8 +36,8 @@ function PdfViewer({ fileUrl, highlightData }) { // Jump to page when highlightData changes useEffect(() => { + highlightData = removeZerosAndDeleteIfAllZero(highlightData); // Removing zeros before checking the highlight data condition if (highlightData && highlightData.length > 0) { - highlightData = removeZerosAndDeleteIfAllZero(highlightData); const pageNumber = highlightData[0][0]; // Assume highlightData[0][0] is the page number if (pageNumber !== null && jumpToPage) { setTimeout(() => { From cebcb113666530ac4d6fa5f3b075807c9e843a82 Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Tue, 17 Dec 2024 15:50:03 +0530 Subject: [PATCH 12/15] required field text changes as per the feedback --- .../src/components/custom-tools/pdf-viewer/PdfViewer.jsx | 2 +- frontend/src/components/custom-tools/prompt-card/Header.jsx | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx b/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx index 3b2e321ca..9103184f6 100644 --- a/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx +++ b/frontend/src/components/custom-tools/pdf-viewer/PdfViewer.jsx @@ -21,7 +21,7 @@ function PdfViewer({ fileUrl, highlightData }) { const { jumpToPage } = pageNavigationPluginInstance; const parentRef = useRef(null); function removeZerosAndDeleteIfAllZero(highlightData) { - return highlightData.filter((innerArray) => + return highlightData?.filter((innerArray) => innerArray.some((value) => value !== 0) ); // Keep arrays that contain at least one non-zero value } diff --git a/frontend/src/components/custom-tools/prompt-card/Header.jsx b/frontend/src/components/custom-tools/prompt-card/Header.jsx index 28f90aa31..97b4a37cb 100644 --- a/frontend/src/components/custom-tools/prompt-card/Header.jsx +++ b/frontend/src/components/custom-tools/prompt-card/Header.jsx @@ -111,7 +111,7 @@ function Header({ checked={required === "all"} onChange={() => handleRequiredChange("all")} > - Required + Value Required )} {enforceType === "json" && ( @@ -120,13 +120,13 @@ function Header({ checked={required === "all"} onChange={() => handleRequiredChange("all")} > - All Required + All JSON Values Required handleRequiredChange("any")} > - Any Required + Atleast 1 JSON Value Required )} From 4def9983923170319325b5e263806be30a8e1fe2 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 06:24:55 +0000 Subject: [PATCH 13/15] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backend/prompt_studio/prompt_studio_core_v2/constants.py | 1 + prompt-service/src/unstract/prompt_service/constants.py | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/prompt_studio/prompt_studio_core_v2/constants.py b/backend/prompt_studio/prompt_studio_core_v2/constants.py index 45329d98e..559fe4f7c 100644 --- a/backend/prompt_studio/prompt_studio_core_v2/constants.py +++ b/backend/prompt_studio/prompt_studio_core_v2/constants.py @@ -99,6 +99,7 @@ class ToolStudioPromptKeys: REQUIRED = "required" EXECUTION_SOURCE = "execution_source" + class FileViewTypes: ORIGINAL = "ORIGINAL" EXTRACT = "EXTRACT" diff --git a/prompt-service/src/unstract/prompt_service/constants.py b/prompt-service/src/unstract/prompt_service/constants.py index 4a64bfb96..8bdaa280b 100644 --- a/prompt-service/src/unstract/prompt_service/constants.py +++ b/prompt-service/src/unstract/prompt_service/constants.py @@ -77,6 +77,7 @@ class PromptServiceContants: EXECUTION_SOURCE = "execution_source" METRICS = "metrics" + class RunLevel(Enum): """Different stages of prompt execution. From b589eee7139ce63c3515848d226696a077e1c019 Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Fri, 20 Dec 2024 12:05:57 +0530 Subject: [PATCH 14/15] addressed pr comments --- .../0005_alter_toolstudioprompt_required.py | 24 +++++++++++++++++++ .../prompt_studio/prompt_studio_v2/models.py | 4 +++- .../src/unstract/prompt_service/helper.py | 21 ---------------- .../src/unstract/prompt_service/main.py | 8 +++---- 4 files changed, 30 insertions(+), 27 deletions(-) create mode 100644 backend/prompt_studio/prompt_studio_v2/migrations/0005_alter_toolstudioprompt_required.py diff --git a/backend/prompt_studio/prompt_studio_v2/migrations/0005_alter_toolstudioprompt_required.py b/backend/prompt_studio/prompt_studio_v2/migrations/0005_alter_toolstudioprompt_required.py new file mode 100644 index 000000000..bdd843050 --- /dev/null +++ b/backend/prompt_studio/prompt_studio_v2/migrations/0005_alter_toolstudioprompt_required.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.1 on 2024-12-20 06:35 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("prompt_studio_v2", "0004_alter_toolstudioprompt_required"), + ] + + operations = [ + migrations.AlterField( + model_name="toolstudioprompt", + name="required", + field=models.CharField( + blank=True, + choices=[("all", "All values required"), ("any", "Any value required")], + db_comment="Field to store weather the values all values or any values required. This is used for HQR, based on the value approve or finish review", + default=None, + null=True, + ), + ), + ] diff --git a/backend/prompt_studio/prompt_studio_v2/models.py b/backend/prompt_studio/prompt_studio_v2/models.py index d520d4958..ccef50ac5 100644 --- a/backend/prompt_studio/prompt_studio_v2/models.py +++ b/backend/prompt_studio/prompt_studio_v2/models.py @@ -93,11 +93,13 @@ class RequiredType(models.TextChoices): unique=False, ) required = models.CharField( - max_length=3, choices=RequiredType.choices, null=True, # Allows the field to store NULL in the database blank=True, # Allows the field to be optional in forms default=None, # Sets the default value to None + db_comment="Field to store weather the values all values or any \ + values required. This is used for HQR, based on the value approve or finish \ + review", ) is_assert = models.BooleanField(default=False) active = models.BooleanField(default=True, null=False, blank=False) diff --git a/prompt-service/src/unstract/prompt_service/helper.py b/prompt-service/src/unstract/prompt_service/helper.py index 999a5744e..a45443d03 100644 --- a/prompt-service/src/unstract/prompt_service/helper.py +++ b/prompt-service/src/unstract/prompt_service/helper.py @@ -396,24 +396,3 @@ def extract_table( except table_extractor["exception_cls"] as e: msg = f"Couldn't extract table. {e}" raise APIError(message=msg) - - -def add_required_field( - required_fields: dict[str, str], key: str, required: str -) -> dict[str, str]: - """ - Add or update a required field in the required_fields dictionary. - - Args: - required_fields (Dict[str, str]): The dictionary - containing existing required fields, - where keys are field names and values are boolean flags. - key (str): The field key to add or update in the dictionary. - required (str): A indicating whether the - all/any values in field is required. - - Returns: - Dict[str, str]: The updated dictionary of required fields. - """ - required_fields[key] = required - return required_fields diff --git a/prompt-service/src/unstract/prompt_service/main.py b/prompt-service/src/unstract/prompt_service/main.py index 25a3776ad..7942ff292 100644 --- a/prompt-service/src/unstract/prompt_service/main.py +++ b/prompt-service/src/unstract/prompt_service/main.py @@ -11,7 +11,6 @@ from unstract.prompt_service.constants import RunLevel from unstract.prompt_service.exceptions import APIError, ErrorResponse, NoPayloadError from unstract.prompt_service.helper import ( - add_required_field, construct_and_run_prompt, extract_table, extract_variable, @@ -125,11 +124,10 @@ def prompt_processor() -> Any: # TODO: Rename "output" to "prompt" for output in prompts: # type:ignore variable_names.append(output[PSKeys.NAME]) - metadata[PSKeys.REQUIRED_FIELDS] = add_required_field( - metadata[PSKeys.REQUIRED_FIELDS], - output[PSKeys.NAME], - output.get(PSKeys.REQUIRED, None), + metadata[PSKeys.REQUIRED_FIELDS][output[PSKeys.NAME]] = output.get( + PSKeys.REQUIRED, None ) + for output in prompts: # type:ignore prompt_name = output[PSKeys.NAME] prompt_text = output[PSKeys.PROMPT] From e7e2237482a4729e4e15fa7edd866282f1e1e743 Mon Sep 17 00:00:00 2001 From: vishnuszipstack Date: Fri, 20 Dec 2024 15:30:48 +0530 Subject: [PATCH 15/15] added info for required fields --- .../components/custom-tools/prompt-card/Header.jsx | 13 ++++++++++++- .../custom-tools/prompt-card/PromptCard.css | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/custom-tools/prompt-card/Header.jsx b/frontend/src/components/custom-tools/prompt-card/Header.jsx index 97b4a37cb..98b0fd2c1 100644 --- a/frontend/src/components/custom-tools/prompt-card/Header.jsx +++ b/frontend/src/components/custom-tools/prompt-card/Header.jsx @@ -6,6 +6,7 @@ import { PlayCircleFilled, PlayCircleOutlined, SyncOutlined, + InfoCircleOutlined, } from "@ant-design/icons"; import { useEffect, useState } from "react"; import { Button, Checkbox, Col, Dropdown, Row, Tag, Tooltip } from "antd"; @@ -111,7 +112,10 @@ function Header({ checked={required === "all"} onChange={() => handleRequiredChange("all")} > - Value Required + Value Required{" "} + + + )} {enforceType === "json" && ( @@ -122,12 +126,19 @@ function Header({ > All JSON Values Required + + + handleRequiredChange("any")} + className="required-checkbox-padding" > Atleast 1 JSON Value Required + + + )} diff --git a/frontend/src/components/custom-tools/prompt-card/PromptCard.css b/frontend/src/components/custom-tools/prompt-card/PromptCard.css index f217c417f..cb8752feb 100644 --- a/frontend/src/components/custom-tools/prompt-card/PromptCard.css +++ b/frontend/src/components/custom-tools/prompt-card/PromptCard.css @@ -299,3 +299,7 @@ .info-circle-colored { color: #f0ad4e; } + +.required-checkbox-padding{ + padding-left: 5px; +}