Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
ef40b15
UN-2807 [FEAT] Add packet processing support for HITL workflows
jagadeeswaran-zipstack Sep 18, 2025
bc31ae5
added missing references
jagadeeswaran-zipstack Sep 19, 2025
969e60c
added hitl prefix to query params
jagadeeswaran-zipstack Oct 1, 2025
996e1a2
Merge branch 'main' into UN-2807-packet-processing-support-in-hitl
jagadeeswaran-zipstack Oct 1, 2025
f10b560
added try-catch on enterprise import
jagadeeswaran-zipstack Oct 3, 2025
f83a9a9
used app registry for plugin check
jagadeeswaran-zipstack Oct 3, 2025
c962b57
Merge branch 'main' into UN-2807-packet-processing-support-in-hitl
jagadeeswaran-zipstack Oct 3, 2025
c2c8ec8
Merge branch 'UN-2807-packet-processing-support-in-hitl' of github.co…
jagadeeswaran-zipstack Oct 3, 2025
028438b
code refactor
jagadeeswaran-zipstack Oct 3, 2025
1c2f26e
used registry to find installed apps
jagadeeswaran-zipstack Oct 5, 2025
0f610b5
sonar issue fix
jagadeeswaran-zipstack Oct 5, 2025
ee1a227
Merge branch 'main' into UN-2807-packet-processing-support-in-hitl
jagadeeswaran-zipstack Oct 6, 2025
3d9013f
Merge branch 'main' of github.com:Zipstack/unstract into UN-2807-pack…
jagadeeswaran-zipstack Oct 8, 2025
0b22c96
Merge branch 'main' of github.com:Zipstack/unstract into UN-2807-pack…
jagadeeswaran-zipstack Oct 8, 2025
74e3260
changes for new worker implementation
jagadeeswaran-zipstack Oct 13, 2025
217026b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Oct 13, 2025
015cd06
Merge branch 'main' into UN-2807-packet-processing-support-in-hitl
athul-rs Oct 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions backend/api_v2/api_deployment_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def post(
tag_names = serializer.validated_data.get(ApiExecution.TAGS)
llm_profile_id = serializer.validated_data.get(ApiExecution.LLM_PROFILE_ID)
hitl_queue_name = serializer.validated_data.get(ApiExecution.HITL_QUEUE_NAME)
hitl_packet_id = serializer.validated_data.get(ApiExecution.HITL_PACKET_ID)
custom_data = serializer.validated_data.get(ApiExecution.CUSTOM_DATA)

if presigned_urls:
Expand All @@ -97,6 +98,7 @@ def post(
tag_names=tag_names,
llm_profile_id=llm_profile_id,
hitl_queue_name=hitl_queue_name,
hitl_packet_id=hitl_packet_id,
custom_data=custom_data,
request_headers=dict(request.headers),
)
Expand Down
1 change: 1 addition & 0 deletions backend/api_v2/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ class ApiExecution:
TAGS: str = "tags"
LLM_PROFILE_ID: str = "llm_profile_id"
HITL_QUEUE_NAME: str = "hitl_queue_name"
HITL_PACKET_ID: str = "hitl_packet_id"
PRESIGNED_URLS: str = "presigned_urls"
CUSTOM_DATA: str = "custom_data"
3 changes: 3 additions & 0 deletions backend/api_v2/deployment_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ def execute_workflow(
tag_names: list[str] = [],
llm_profile_id: str | None = None,
hitl_queue_name: str | None = None,
hitl_packet_id: str | None = None,
custom_data: dict[str, Any] | None = None,
request_headers=None,
) -> ReturnDict:
Expand All @@ -169,6 +170,7 @@ def execute_workflow(
tag_names (list(str)): list of tag names
llm_profile_id (str, optional): LLM profile ID for overriding tool settings
hitl_queue_name (str, optional): Custom queue name for manual review
hitl_packet_id (str, optional): Packet ID for packet-based review
custom_data (dict[str, Any], optional): JSON data for custom_data variable replacement in prompts

Returns:
Expand Down Expand Up @@ -236,6 +238,7 @@ def execute_workflow(
use_file_history=use_file_history,
llm_profile_id=llm_profile_id,
hitl_queue_name=hitl_queue_name,
hitl_packet_id=hitl_packet_id,
custom_data=custom_data,
)
result.status_api = DeploymentHelper.construct_status_endpoint(
Expand Down
32 changes: 32 additions & 0 deletions backend/api_v2/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Any
from urllib.parse import urlparse

from django.apps import apps
from django.core.validators import RegexValidator
from pipeline_v2.models import Pipeline
from prompt_studio.prompt_profile_manager_v2.models import ProfileManager
Expand Down Expand Up @@ -227,6 +228,7 @@ class ExecutionRequestSerializer(TagParamsSerializer):
presigned_urls = ListField(child=URLField(), required=False)
llm_profile_id = CharField(required=False, allow_null=True, allow_blank=True)
hitl_queue_name = CharField(required=False, allow_null=True, allow_blank=True)
hitl_packet_id = CharField(required=False, allow_null=True, allow_blank=True)
custom_data = JSONField(required=False, allow_null=True)

def validate_hitl_queue_name(self, value: str | None) -> str | None:
Expand All @@ -248,6 +250,36 @@ def validate_hitl_queue_name(self, value: str | None) -> str | None:
)
return value

def validate_hitl_packet_id(self, value: str | None) -> str | None:
"""Validate packet ID format using enterprise validation if available."""
if not value:
return value

# Check if HITL feature is available
if not apps.is_installed("pluggable_apps.manual_review_v2"):
raise ValidationError(
"Packet-based HITL processing requires Unstract Enterprise. "
"This advanced workflow feature is available in our enterprise version. "
"Learn more at https://docs.unstract.com/unstract/unstract_platform/features/workflows/hqr_deployment_workflows/ or "
"contact our sales team at https://unstract.com/contact/"
)

# Validate packet ID format (alphanumeric string, typically 8-character hex)
value = value.strip()
if not value:
raise ValidationError("Packet ID cannot be empty or whitespace only.")

# Basic format validation: alphanumeric, reasonable length
if not re.match(r"^[a-zA-Z0-9_-]+$", value):
raise ValidationError(
"Invalid packet ID format. Packet ID must contain only letters, numbers, hyphens, or underscores."
)

if len(value) > 16: # Reasonable max length
raise ValidationError("Packet ID is too long (maximum 100 characters).")

return value

def validate_custom_data(self, value):
"""Validate custom_data is a valid JSON object."""
if value is None:
Expand Down
Loading