mirror of
https://github.com/FuzzingLabs/fuzzforge_ai.git
synced 2026-02-25 11:45:17 +00:00
chore: Complete Temporal migration with updated CLI/SDK/docs
This commit includes all remaining Temporal migration changes: ## CLI Updates (cli/) - Updated workflow execution commands for Temporal - Enhanced error handling and exceptions - Updated dependencies in uv.lock ## SDK Updates (sdk/) - Client methods updated for Temporal workflows - Updated models for new workflow execution - Updated dependencies in uv.lock ## Documentation Updates (docs/) - Architecture documentation for Temporal - Workflow concept documentation - Resource management documentation (new) - Debugging guide (new) - Updated tutorials and how-to guides - Troubleshooting updates ## README Updates - Main README with Temporal instructions - Backend README - CLI README - SDK README ## Other - Updated IMPLEMENTATION_STATUS.md - Removed old vulnerable_app.tar.gz These changes complete the Temporal migration and ensure the CLI/SDK work correctly with the new backend.
This commit is contained in:
@@ -77,7 +77,7 @@ def execute_workflow_submission(
|
||||
timeout: Optional[int],
|
||||
interactive: bool
|
||||
) -> Any:
|
||||
"""Handle the workflow submission process"""
|
||||
"""Handle the workflow submission process with file upload"""
|
||||
# Get workflow metadata for parameter validation
|
||||
console.print(f"🔧 Getting workflow information for: {workflow}")
|
||||
workflow_meta = client.get_workflow_metadata(workflow)
|
||||
@@ -87,7 +87,7 @@ def execute_workflow_submission(
|
||||
if interactive and workflow_meta.parameters.get("properties"):
|
||||
properties = workflow_meta.parameters.get("properties", {})
|
||||
required_params = set(workflow_meta.parameters.get("required", []))
|
||||
defaults = param_response.defaults
|
||||
defaults = param_response.default_parameters
|
||||
|
||||
missing_required = required_params - set(parameters.keys())
|
||||
|
||||
@@ -131,14 +131,6 @@ def execute_workflow_submission(
|
||||
f"one of: {', '.join(workflow_meta.supported_volume_modes)}"
|
||||
)
|
||||
|
||||
# Create submission
|
||||
submission = WorkflowSubmission(
|
||||
target_path=target_path,
|
||||
volume_mode=volume_mode,
|
||||
parameters=parameters,
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
# Show submission summary
|
||||
console.print(f"\n🎯 [bold]Executing workflow:[/bold]")
|
||||
console.print(f" Workflow: {workflow}")
|
||||
@@ -149,6 +141,22 @@ def execute_workflow_submission(
|
||||
if timeout:
|
||||
console.print(f" Timeout: {timeout}s")
|
||||
|
||||
# Check if target path exists locally
|
||||
target_path_obj = Path(target_path)
|
||||
use_upload = target_path_obj.exists()
|
||||
|
||||
if use_upload:
|
||||
# Show file/directory info
|
||||
if target_path_obj.is_dir():
|
||||
num_files = sum(1 for _ in target_path_obj.rglob("*") if _.is_file())
|
||||
console.print(f" Upload: Directory with {num_files} files")
|
||||
else:
|
||||
size_mb = target_path_obj.stat().st_size / (1024 * 1024)
|
||||
console.print(f" Upload: File ({size_mb:.2f} MB)")
|
||||
else:
|
||||
console.print(f" [yellow]⚠️ Warning: Target path does not exist locally[/yellow]")
|
||||
console.print(f" [yellow] Attempting to use path-based submission (backend must have access)[/yellow]")
|
||||
|
||||
# Only ask for confirmation in interactive mode
|
||||
if interactive:
|
||||
if not Confirm.ask("\nExecute workflow?", default=True, console=console):
|
||||
@@ -160,32 +168,75 @@ def execute_workflow_submission(
|
||||
# Submit the workflow with enhanced progress
|
||||
console.print(f"\n🚀 Executing workflow: [bold yellow]{workflow}[/bold yellow]")
|
||||
|
||||
steps = [
|
||||
"Validating workflow configuration",
|
||||
"Connecting to FuzzForge API",
|
||||
"Uploading parameters and settings",
|
||||
"Creating workflow deployment",
|
||||
"Initializing execution environment"
|
||||
]
|
||||
if use_upload:
|
||||
# Use new upload-based submission
|
||||
steps = [
|
||||
"Validating workflow configuration",
|
||||
"Creating tarball (if directory)",
|
||||
"Uploading target to backend",
|
||||
"Starting workflow execution",
|
||||
"Initializing execution environment"
|
||||
]
|
||||
|
||||
with step_progress(steps, f"Executing {workflow}") as progress:
|
||||
progress.next_step() # Validating
|
||||
time.sleep(PROGRESS_STEP_DELAYS["validating"])
|
||||
with step_progress(steps, f"Executing {workflow}") as progress:
|
||||
progress.next_step() # Validating
|
||||
time.sleep(PROGRESS_STEP_DELAYS["validating"])
|
||||
|
||||
progress.next_step() # Connecting
|
||||
time.sleep(PROGRESS_STEP_DELAYS["connecting"])
|
||||
progress.next_step() # Creating tarball
|
||||
time.sleep(PROGRESS_STEP_DELAYS["connecting"])
|
||||
|
||||
progress.next_step() # Uploading
|
||||
response = client.submit_workflow(workflow, submission)
|
||||
time.sleep(PROGRESS_STEP_DELAYS["uploading"])
|
||||
progress.next_step() # Uploading
|
||||
# Use the new upload method
|
||||
response = client.submit_workflow_with_upload(
|
||||
workflow_name=workflow,
|
||||
target_path=target_path,
|
||||
parameters=parameters,
|
||||
volume_mode=volume_mode,
|
||||
timeout=timeout
|
||||
)
|
||||
time.sleep(PROGRESS_STEP_DELAYS["uploading"])
|
||||
|
||||
progress.next_step() # Creating deployment
|
||||
time.sleep(PROGRESS_STEP_DELAYS["creating"])
|
||||
progress.next_step() # Starting
|
||||
time.sleep(PROGRESS_STEP_DELAYS["creating"])
|
||||
|
||||
progress.next_step() # Initializing
|
||||
time.sleep(PROGRESS_STEP_DELAYS["initializing"])
|
||||
progress.next_step() # Initializing
|
||||
time.sleep(PROGRESS_STEP_DELAYS["initializing"])
|
||||
|
||||
progress.complete(f"Workflow started successfully!")
|
||||
progress.complete(f"Workflow started successfully!")
|
||||
else:
|
||||
# Fall back to path-based submission (for backward compatibility)
|
||||
steps = [
|
||||
"Validating workflow configuration",
|
||||
"Connecting to FuzzForge API",
|
||||
"Submitting workflow parameters",
|
||||
"Creating workflow deployment",
|
||||
"Initializing execution environment"
|
||||
]
|
||||
|
||||
with step_progress(steps, f"Executing {workflow}") as progress:
|
||||
progress.next_step() # Validating
|
||||
time.sleep(PROGRESS_STEP_DELAYS["validating"])
|
||||
|
||||
progress.next_step() # Connecting
|
||||
time.sleep(PROGRESS_STEP_DELAYS["connecting"])
|
||||
|
||||
progress.next_step() # Submitting
|
||||
submission = WorkflowSubmission(
|
||||
target_path=target_path,
|
||||
volume_mode=volume_mode,
|
||||
parameters=parameters,
|
||||
timeout=timeout
|
||||
)
|
||||
response = client.submit_workflow(workflow, submission)
|
||||
time.sleep(PROGRESS_STEP_DELAYS["uploading"])
|
||||
|
||||
progress.next_step() # Creating deployment
|
||||
time.sleep(PROGRESS_STEP_DELAYS["creating"])
|
||||
|
||||
progress.next_step() # Initializing
|
||||
time.sleep(PROGRESS_STEP_DELAYS["initializing"])
|
||||
|
||||
progress.complete(f"Workflow started successfully!")
|
||||
|
||||
return response
|
||||
|
||||
|
||||
@@ -193,7 +193,7 @@ def workflow_parameters(
|
||||
parameters = {}
|
||||
properties = workflow.parameters.get("properties", {})
|
||||
required_params = set(workflow.parameters.get("required", []))
|
||||
defaults = param_response.defaults
|
||||
defaults = param_response.default_parameters
|
||||
|
||||
if interactive:
|
||||
console.print("🔧 Enter parameter values (press Enter for default):\n")
|
||||
|
||||
@@ -430,8 +430,9 @@ def validate_run_id(run_id: str) -> str:
|
||||
if not run_id or len(run_id) < 8:
|
||||
raise ValidationError("run_id", run_id, "at least 8 characters")
|
||||
|
||||
if not run_id.replace('-', '').isalnum():
|
||||
raise ValidationError("run_id", run_id, "alphanumeric characters and hyphens only")
|
||||
# Allow alphanumeric characters, hyphens, and underscores
|
||||
if not run_id.replace('-', '').replace('_', '').isalnum():
|
||||
raise ValidationError("run_id", run_id, "alphanumeric characters, hyphens, and underscores only")
|
||||
|
||||
return run_id
|
||||
|
||||
|
||||
Reference in New Issue
Block a user