Skip to content

Commit b6057e8

Browse files
[FEATURE] Changes required for highlighting (#555)
* Changes for highlighting in prompt studio Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * Precommit fixes Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * Send metadata always from prompt-studio Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * pre-commit fix Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * SDK version bump Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * Dependency resolution Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * Update pdm.lock for unstract/core * Send metadata by default and remove it based on include_metadata Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * Minor refactor for prompt-service Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * Minor fix in structure tool Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * Update pdm.lock for prompt-service * Update pdm.lock for backend * Update pdm.lock for root * Highlight related changes in tool Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * Optimized code and reverted unwanted code Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> * Bumped structure tool version Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> --------- Signed-off-by: Deepak <89829542+Deepak-Kesavan@users.noreply.github.com> Signed-off-by: Deepak K <89829542+Deepak-Kesavan@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 27f3e91 commit b6057e8

28 files changed

Lines changed: 360 additions & 215 deletions

File tree

backend/api/api_deployment_views.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def get(
7474
self, request: Request, org_name: str, api_name: str, api: APIDeployment
7575
) -> Response:
7676
execution_id = request.query_params.get("execution_id")
77+
include_metadata = request.query_params.get("include_metadata", False)
7778
if not execution_id:
7879
raise InvalidAPIRequest("execution_id shouldn't be empty")
7980
response: ExecutionResponse = DeploymentHelper.get_execution_status(
@@ -87,6 +88,11 @@ def get(
8788
},
8889
status=status.HTTP_422_UNPROCESSABLE_ENTITY,
8990
)
91+
if (
92+
response.execution_status == CeleryTaskState.SUCCESS.value
93+
and not include_metadata
94+
):
95+
response.remove_result_metadata_keys()
9096
return Response(
9197
{"status": response.execution_status, "message": response.result},
9298
status=status.HTTP_200_OK,

backend/api/deployment_helper.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,13 @@ def execute_workflow(
174174
hash_values_of_files=hash_values_of_files,
175175
timeout=timeout,
176176
execution_id=execution_id,
177-
include_metadata=include_metadata,
178177
)
179178
result.status_api = DeploymentHelper.construct_status_endpoint(
180179
api_endpoint=api.api_endpoint, execution_id=execution_id
181180
)
181+
if not include_metadata:
182+
result.remove_result_metadata_keys()
183+
cls._send_notification(api=api, result=result)
182184
except Exception as error:
183185
DestinationConnector.delete_api_storage_dir(
184186
workflow_id=workflow_id, execution_id=execution_id

backend/file_management/file_management_helper.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,15 +223,22 @@ def delete_related_files(
223223
) -> bool:
224224
fs = file_system.get_fsspec_fs()
225225
base_path = FileManagerHelper._get_base_path(file_system, path)
226-
227226
base_file_name, _ = os.path.splitext(file_name)
228-
file_name_txt = base_file_name + ".txt"
229-
230-
for directory in directories:
231-
file_path = str(Path(base_path) / directory / file_name_txt)
227+
pattern = f"{base_file_name}.*"
228+
file_paths = FileManagerHelper._find_files(fs, base_path, directories, pattern)
229+
for file_path in file_paths:
232230
FileManagerHelper._delete_file(fs, file_path)
233231
return True
234232

233+
@staticmethod
234+
def _find_files(fs, base_path: str, directories: list[str], pattern: str):
235+
file_paths = []
236+
for directory in directories:
237+
directory_path = str(Path(base_path) / directory)
238+
for file in fs.glob(f"{directory_path}/{pattern}"):
239+
file_paths.append(file)
240+
return file_paths
241+
235242
@staticmethod
236243
def handle_sub_directory_for_tenants(
237244
org_id: str, user_id: str, tool_id: str, is_create: bool

backend/prompt_studio/processor_loader.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,13 @@ def load_plugins() -> list[Any]:
7272
logger.info("No processor plugins found.")
7373

7474
return processor_plugins
75+
76+
77+
def get_plugin_class_by_name(name: str, plugins: list[Any]) -> Any:
78+
"""Retrieve a specific plugin class by name."""
79+
for plugin in plugins:
80+
metadata = plugin[ProcessorConfig.METADATA]
81+
if metadata.get(ProcessorConfig.METADATA_NAME) == name:
82+
return metadata.get(ProcessorConfig.METADATA_SERVICE_CLASS)
83+
logger.warning("Plugin with name '%s' not found.", name)
84+
return None

backend/prompt_studio/prompt_studio_core/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ class ToolStudioPromptKeys:
6262
WORD = "word"
6363
SYNONYMS = "synonyms"
6464
OUTPUTS = "outputs"
65-
ASSERT_PROMPT = "assert_prompt"
6665
SECTION = "section"
6766
DEFAULT = "default"
6867
REINDEX = "reindex"
@@ -89,6 +88,7 @@ class ToolStudioPromptKeys:
8988
CONTEXT = "context"
9089
METADATA = "metadata"
9190
INCLUDE_METADATA = "include_metadata"
91+
PLATFORM_POSTAMBLE = "platform_postamble"
9292

9393

9494
class FileViewTypes:

backend/prompt_studio/prompt_studio_core/prompt_studio_helper.py

Lines changed: 66 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
import uuid
55
from pathlib import Path
6-
from typing import Any, Optional
6+
from typing import Any, Callable, Optional
77

88
from account.constants import Common
99
from account.models import User
@@ -291,6 +291,7 @@ def index_document(
291291
document_id: str,
292292
is_summary: bool = False,
293293
run_id: str = None,
294+
text_processor: Optional[type[Any]] = None,
294295
) -> Any:
295296
"""Method to index a document.
296297
@@ -340,7 +341,9 @@ def index_document(
340341
# Need to check the user who created profile manager
341342
# has access to adapters configured in profile manager
342343
PromptStudioHelper.validate_profile_manager_owner_access(default_profile)
343-
344+
process_text = None
345+
if text_processor:
346+
process_text = text_processor.process
344347
doc_id = PromptStudioHelper.dynamic_indexer(
345348
profile_manager=default_profile,
346349
tool_id=tool_id,
@@ -351,6 +354,7 @@ def index_document(
351354
reindex=True,
352355
run_id=run_id,
353356
user_id=user_id,
357+
process_text=process_text,
354358
)
355359

356360
logger.info(f"[{tool_id}] Indexing successful for doc: {file_name}")
@@ -372,6 +376,7 @@ def prompt_responder(
372376
id: Optional[str] = None,
373377
run_id: str = None,
374378
profile_manager_id: Optional[str] = None,
379+
text_processor: Optional[type[Any]] = None,
375380
) -> Any:
376381
"""Execute chain/single run of the prompts. Makes a call to prompt
377382
service and returns the dict of response.
@@ -398,19 +403,26 @@ def prompt_responder(
398403

399404
if id:
400405
return PromptStudioHelper._execute_single_prompt(
401-
id,
402-
doc_path,
403-
doc_name,
404-
tool_id,
405-
org_id,
406-
user_id,
407-
document_id,
408-
run_id,
409-
profile_manager_id,
406+
id=id,
407+
doc_path=doc_path,
408+
doc_name=doc_name,
409+
tool_id=tool_id,
410+
org_id=org_id,
411+
user_id=user_id,
412+
document_id=document_id,
413+
run_id=run_id,
414+
profile_manager_id=profile_manager_id,
415+
text_processor=text_processor,
410416
)
411417
else:
412418
return PromptStudioHelper._execute_prompts_in_single_pass(
413-
doc_path, tool_id, org_id, user_id, document_id, run_id
419+
doc_path=doc_path,
420+
tool_id=tool_id,
421+
org_id=org_id,
422+
user_id=user_id,
423+
document_id=document_id,
424+
run_id=run_id,
425+
text_processor=text_processor,
414426
)
415427

416428
@staticmethod
@@ -424,6 +436,7 @@ def _execute_single_prompt(
424436
document_id,
425437
run_id,
426438
profile_manager_id,
439+
text_processor: Optional[type[Any]] = None,
427440
):
428441
prompt_instance = PromptStudioHelper._fetch_prompt_from_id(id)
429442
prompt_name = prompt_instance.prompt_key
@@ -458,7 +471,9 @@ def _execute_single_prompt(
458471
LogLevels.RUN,
459472
"Invoking prompt service",
460473
)
461-
474+
process_text = None
475+
if text_processor:
476+
process_text = text_processor.process
462477
try:
463478
response = PromptStudioHelper._fetch_response(
464479
doc_path=doc_path,
@@ -470,9 +485,15 @@ def _execute_single_prompt(
470485
run_id=run_id,
471486
profile_manager_id=profile_manager_id,
472487
user_id=user_id,
488+
process_text=process_text,
473489
)
474490
return PromptStudioHelper._handle_response(
475-
response, run_id, prompts, document_id, False, profile_manager_id
491+
response=response,
492+
run_id=run_id,
493+
prompts=prompts,
494+
document_id=document_id,
495+
is_single_pass=False,
496+
profile_manager_id=profile_manager_id,
476497
)
477498
except Exception as e:
478499
logger.error(
@@ -495,7 +516,13 @@ def _execute_single_prompt(
495516

496517
@staticmethod
497518
def _execute_prompts_in_single_pass(
498-
doc_path, tool_id, org_id, user_id, document_id, run_id
519+
doc_path,
520+
tool_id,
521+
org_id,
522+
user_id,
523+
document_id,
524+
run_id,
525+
text_processor: Optional[type[Any]] = None,
499526
):
500527
prompts = PromptStudioHelper.fetch_prompt_from_tool(tool_id)
501528
prompts = [
@@ -513,7 +540,9 @@ def _execute_prompts_in_single_pass(
513540
LogLevels.RUN,
514541
"Executing prompts in single pass",
515542
)
516-
543+
process_text = None
544+
if text_processor:
545+
process_text = text_processor.process
517546
try:
518547
tool = prompts[0].tool_id
519548
response = PromptStudioHelper._fetch_single_pass_response(
@@ -524,9 +553,14 @@ def _execute_prompts_in_single_pass(
524553
document_id=document_id,
525554
run_id=run_id,
526555
user_id=user_id,
556+
process_text=process_text,
527557
)
528558
return PromptStudioHelper._handle_response(
529-
response, run_id, prompts, document_id, True
559+
response=response,
560+
run_id=run_id,
561+
prompts=prompts,
562+
document_id=document_id,
563+
is_single_pass=True,
530564
)
531565
except Exception as e:
532566
logger.error(
@@ -556,7 +590,12 @@ def _get_document_path(org_id, user_id, tool_id, doc_name):
556590

557591
@staticmethod
558592
def _handle_response(
559-
response, run_id, prompts, document_id, is_single_pass, profile_manager_id=None
593+
response,
594+
run_id,
595+
prompts,
596+
document_id,
597+
is_single_pass,
598+
profile_manager_id=None,
560599
):
561600
if response.get("status") == IndexingStatus.PENDING_STATUS.value:
562601
return {
@@ -586,6 +625,7 @@ def _fetch_response(
586625
run_id: str,
587626
user_id: str,
588627
profile_manager_id: Optional[str] = None,
628+
process_text: Optional[Callable[[str], str]] = None,
589629
) -> Any:
590630
"""Utility function to invoke prompt service. Used internally.
591631
@@ -656,6 +696,7 @@ def _fetch_response(
656696
is_summary=tool.summarize_as_source,
657697
run_id=run_id,
658698
user_id=user_id,
699+
process_text=process_text,
659700
)
660701
if index_result.get("status") == IndexingStatus.PENDING_STATUS.value:
661702
return {
@@ -713,6 +754,9 @@ def _fetch_response(
713754
tool_settings[TSPKeys.PREAMBLE] = tool.preamble
714755
tool_settings[TSPKeys.POSTAMBLE] = tool.postamble
715756
tool_settings[TSPKeys.GRAMMAR] = grammar_list
757+
tool_settings[TSPKeys.PLATFORM_POSTAMBLE] = getattr(
758+
settings, TSPKeys.PLATFORM_POSTAMBLE.upper(), ""
759+
)
716760

717761
tool_id = str(tool.tool_id)
718762

@@ -760,6 +804,7 @@ def dynamic_indexer(
760804
is_summary: bool = False,
761805
reindex: bool = False,
762806
run_id: str = None,
807+
process_text: Optional[Callable[[str], str]] = None,
763808
) -> Any:
764809
"""Used to index a file based on the passed arguments.
765810
@@ -842,6 +887,7 @@ def dynamic_indexer(
842887
reindex=reindex,
843888
output_file_path=extract_file_path,
844889
usage_kwargs=usage_kwargs.copy(),
890+
process_text=process_text,
845891
)
846892

847893
PromptStudioIndexHelper.handle_index_manager(
@@ -875,6 +921,7 @@ def _fetch_single_pass_response(
875921
user_id: str,
876922
document_id: str,
877923
run_id: str = None,
924+
process_text: Optional[Callable[[str], str]] = None,
878925
) -> Any:
879926
tool_id: str = str(tool.tool_id)
880927
outputs: list[dict[str, Any]] = []
@@ -910,6 +957,7 @@ def _fetch_single_pass_response(
910957
document_id=document_id,
911958
run_id=run_id,
912959
user_id=user_id,
960+
process_text=process_text,
913961
)
914962
if index_result.get("status") == IndexingStatus.PENDING_STATUS.value:
915963
return {

0 commit comments

Comments
 (0)