delightfulrachel commited on
Commit
7b5f2bf
·
verified ·
1 Parent(s): 19b1ede

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +204 -129
app.py CHANGED
@@ -161,10 +161,9 @@ def call_together_api(model: str, prompt: str, temperature: float = 0.7, max_tok
161
  """Call Together AI API with enhanced error handling."""
162
  api_key = get_api_key("together")
163
  system_message = (
164
- "You are a Salesforce development expert specializing in B2B Commerce migrations, "
165
- "CloudCraze to B2B Lightning Experience conversions, and Apex code optimization. "
166
- "You have a skeptical and thorough approach to code review, always checking for "
167
- "syntax errors, security vulnerabilities, and performance issues."
168
  )
169
 
170
  def make_request():
@@ -199,10 +198,9 @@ def call_anthropic_api(model: str, prompt: str, temperature: float = 0.7, max_to
199
  """Call Anthropic API with enhanced error handling."""
200
  api_key = get_api_key("anthropic")
201
  system_message = (
202
- "You are a Salesforce development expert specializing in B2B Commerce migrations, "
203
- "CloudCraze to B2B Lightning Experience conversions, and Apex code optimization. "
204
- "You have a skeptical and thorough approach to code review, always checking for "
205
- "syntax errors, security vulnerabilities, and performance issues."
206
  )
207
 
208
  def make_request():
@@ -353,25 +351,51 @@ def extract_code_blocks(text: str) -> str:
353
 
354
  return '\n\n'.join(filter(None, code_blocks))
355
 
356
- def extract_explanations(text: str, code_blocks: str) -> str:
357
- """Extract explanations by removing code blocks from the response."""
358
- explanation = text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
359
 
360
- # Remove code blocks
361
- if code_blocks:
362
- for block in code_blocks.split('\n\n'):
363
- if block.strip():
364
- # Escape special regex characters
365
- escaped_block = re.escape(block)
366
- explanation = re.sub(escaped_block, "", explanation, flags=re.DOTALL)
367
 
368
- # Remove code block markers
369
- explanation = re.sub(r"```(?:apex|java|Apex|Java|APEX|JAVA)?.*?```", "*[Code moved to Code Output section]*", explanation, flags=re.DOTALL)
370
 
371
- # Clean up extra whitespace
372
- explanation = re.sub(r'\n{3,}', '\n\n', explanation)
373
 
374
- return explanation.strip()
 
 
 
 
 
 
 
 
375
 
376
  def perform_skeptical_evaluation(code: str, context: str = "trigger") -> Dict[str, any]:
377
  """Perform skeptical evaluation of code looking for common issues."""
@@ -527,45 +551,48 @@ def correct_apex_trigger(model: str, trigger_code: str, progress=None) -> Tuple[
527
  # Perform skeptical evaluation
528
  evaluation = perform_skeptical_evaluation(trigger_code, "trigger")
529
 
530
- # Build comprehensive prompt
531
  prompt = f"""
532
- You are tasked with correcting and optimizing the following Apex Trigger for migration from CloudCraze to B2B Lightning Experience.
533
-
534
- IMPORTANT: Apply a SKEPTICAL lens to this code. Assume there are hidden issues and actively look for:
535
- 1. Syntax errors (missing semicolons, brackets, incorrect method signatures)
536
- 2. Logic errors (null pointer exceptions, incorrect loop conditions)
537
- 3. Security vulnerabilities (FLS violations, SOQL injection risks)
538
- 4. Performance issues (queries in loops, inefficient algorithms)
539
- 5. Governor limit risks (excessive DML, SOQL operations)
540
- 6. B2B Commerce specific issues (deprecated CloudCraze methods, incorrect object mappings)
541
-
542
- Initial Analysis Found:
543
- - Syntax Issues: {len(syntax_issues)}
544
- - Security Concerns: {len(evaluation['security_concerns'])}
545
  - Performance Issues: {len(evaluation['performance_issues'])}
546
  - B2B Commerce Issues: {len(evaluation['b2b_commerce_issues'])}
547
 
548
- ORIGINAL TRIGGER CODE:
 
 
549
  ```apex
550
- {trigger_code}
551
  ```
552
 
553
- REQUIREMENTS:
554
- 1. Fix ALL syntax errors
555
- 2. Implement proper bulkification
556
- 3. Add comprehensive error handling
557
- 4. Ensure FLS/CRUD security
558
- 5. Optimize for performance
559
- 6. Migrate CloudCraze references to B2B Lightning Experience
560
- 7. Add detailed comments explaining each fix
 
 
 
 
561
 
562
- Return the corrected code in ```apex blocks with detailed explanations of ALL changes made.
563
  """
564
 
565
  if progress:
566
  progress(0.5, desc="Calling AI model...")
567
 
568
- response = call_llm(model, prompt, temperature=0.3) # Lower temperature for more consistent corrections
569
 
570
  if progress:
571
  progress(0.8, desc="Processing response...")
@@ -574,17 +601,23 @@ Return the corrected code in ```apex blocks with detailed explanations of ALL ch
574
  code_output = extract_code_blocks(response)
575
 
576
  # Validate the corrected code
 
577
  if code_output:
578
  corrected_valid, corrected_issues = validate_apex_syntax(code_output)
579
  if not corrected_valid:
580
- # Add warning to explanation
581
- response += f"\n\n⚠️ WARNING: The corrected code still has {len(corrected_issues)} syntax issues that need manual review."
 
582
 
583
- explanation = extract_explanations(response, code_output)
 
584
 
585
- # Add test case template
586
- test_template = generate_test_cases("trigger", code_output)
587
- explanation += f"\n\n### Suggested Test Class Template:\n```apex\n{test_template}\n```"
 
 
 
588
 
589
  if progress:
590
  progress(1.0, desc="Complete!")
@@ -615,52 +648,63 @@ def convert_cc_object(model: str, cc_object_code: str, progress=None) -> Tuple[s
615
  evaluation = perform_skeptical_evaluation(cc_object_code, "object")
616
 
617
  prompt = f"""
618
- You are tasked with converting CloudCraze Object code to B2B Lightning Experience format.
619
-
620
- IMPORTANT: Apply a SKEPTICAL lens to this conversion. Actively look for:
621
- 1. Missing or incorrectly mapped fields
622
- 2. Data type mismatches between CloudCraze and B2B LEX
623
- 3. Relationship mapping issues
624
- 4. Custom fields that have no B2B LEX equivalent
625
- 5. Business logic embedded in CloudCraze that needs migration
626
- 6. Data migration challenges (data format changes, validation rules)
627
 
628
- CLOUDCRAZE OBJECT CODE:
629
  ```
630
  {cc_object_code}
631
  ```
632
 
633
- REQUIREMENTS:
634
- 1. Identify the exact B2B LEX object mapping
635
- 2. Map ALL fields with data type conversions
636
- 3. Handle custom fields appropriately
637
- 4. Document any data migration considerations
638
- 5. Provide complete implementation code
639
- 6. Include data migration script if needed
640
- 7. List any manual steps required
641
-
642
- Return:
643
- 1. Complete B2B LEX object implementation in ```apex blocks
644
- 2. Field mapping table
645
- 3. Data migration considerations
646
- 4. Manual migration steps if any
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
647
  """
648
 
649
  if progress:
650
  progress(0.5, desc="Calling AI model...")
651
 
652
- response = call_llm(model, prompt, temperature=0.3)
653
 
654
  if progress:
655
  progress(0.8, desc="Processing response...")
656
 
657
  # Extract code and explanations
658
  code_output = extract_code_blocks(response)
659
- explanation = extract_explanations(response, code_output)
660
 
661
- # Add test case template
662
- test_template = generate_test_cases("object", code_output)
663
- explanation += f"\n\n### Suggested Test Data Creation:\n```apex\n{test_template}\n```"
 
 
664
 
665
  if progress:
666
  progress(1.0, desc="Complete!")
@@ -778,7 +822,7 @@ def create_enhanced_radar_chart(metrics: Optional[Dict[str, float]]) -> Optional
778
  return fig
779
 
780
  def validate_apex_trigger(validation_model: str, original_code: str, corrected_code: str) -> str:
781
- """Enhanced validation with skeptical evaluation."""
782
  if not validation_model or not original_code.strip() or not corrected_code.strip():
783
  return "Please provide all required inputs for validation."
784
 
@@ -787,80 +831,111 @@ def validate_apex_trigger(validation_model: str, original_code: str, corrected_c
787
  corr_valid, corr_issues = validate_apex_syntax(corrected_code)
788
 
789
  prompt = f"""
790
- You are performing a SKEPTICAL validation of an Apex code migration. Your job is to find problems, not to praise.
791
 
792
- ORIGINAL CODE (had {len(orig_issues)} issues):
793
  ```apex
794
  {original_code}
795
  ```
796
 
797
- CORRECTED CODE (has {len(corr_issues)} issues):
798
  ```apex
799
  {corrected_code}
800
  ```
801
 
802
- CRITICAL EVALUATION REQUIRED:
803
- 1. List ALL remaining syntax errors in the corrected code
804
- 2. Identify any NEW issues introduced by the correction
805
- 3. Find security vulnerabilities (FLS, CRUD, injection risks)
806
- 4. Identify performance problems (O(n²) algorithms, unbounded queries)
807
- 5. Check governor limit risks (queries/DML in loops)
808
- 6. Verify B2B Commerce migration completeness
809
- 7. Look for edge cases not handled
810
- 8. Check error handling completeness
811
-
812
- IMPORTANT: Be harsh but fair. If the correction is genuinely good, acknowledge it, but still look for improvements.
 
 
 
 
 
 
 
 
 
 
 
 
 
813
 
814
- Provide your assessment in this JSON format:
815
- {json.dumps(VALIDATION_SCHEMA, indent=2)}
 
 
 
 
 
 
816
 
817
- Be specific about line numbers and provide actionable feedback.
818
  """
819
 
820
- return call_llm(validation_model, prompt, temperature=0.2) # Very low temperature for consistent validation
821
 
822
  def validate_cc_object_conversion(validation_model: str, original_object: str, converted_object: str) -> str:
823
- """Enhanced validation for CloudCraze object conversion."""
824
  if not validation_model or not original_object.strip() or not converted_object.strip():
825
  return "Please provide all required inputs for validation."
826
 
827
  prompt = f"""
828
- You are performing a SKEPTICAL validation of a CloudCraze to B2B Lightning Experience object conversion.
829
 
830
- ORIGINAL CLOUDCRAZE OBJECT:
831
  ```
832
  {original_object}
833
  ```
834
 
835
- CONVERTED B2B LEX OBJECT:
836
  ```
837
  {converted_object}
838
  ```
839
 
840
- CRITICAL EVALUATION REQUIRED:
841
- 1. Verify EVERY field is mapped correctly (check data types!)
842
- 2. Identify missing fields or relationships
843
- 3. Check for custom field handling
844
- 4. Validate business logic migration
845
- 5. Identify data migration challenges
846
- 6. Check for hardcoded values that should be configurable
847
- 7. Verify object security settings
848
- 8. Look for performance implications
849
-
850
- SPECIFIC CHECKS:
851
- - Are all CloudCraze custom fields accounted for?
852
- - Are relationship fields properly mapped?
853
- - Are there data type mismatches?
854
- - Are validation rules considered?
855
- - Is the object scalable for large data volumes?
856
-
857
- Provide your assessment in this JSON format:
858
- {json.dumps(VALIDATION_SCHEMA, indent=2)}
859
-
860
- Include specific examples of issues found.
 
 
 
 
 
 
 
 
 
 
 
 
861
  """
862
 
863
- return call_llm(validation_model, prompt, temperature=0.2)
864
 
865
  def get_theme_styles(theme_choice: str) -> Tuple[str, str, str, str]:
866
  """Get theme styles for different UI elements."""
 
161
  """Call Together AI API with enhanced error handling."""
162
  api_key = get_api_key("together")
163
  system_message = (
164
+ "You are a Salesforce B2B Commerce expert. Be CONCISE and PRECISE. "
165
+ "Focus on CODE QUALITY over explanations. Use structured formats when requested. "
166
+ "Always check for syntax errors, security issues, and performance problems."
 
167
  )
168
 
169
  def make_request():
 
198
  """Call Anthropic API with enhanced error handling."""
199
  api_key = get_api_key("anthropic")
200
  system_message = (
201
+ "You are a Salesforce B2B Commerce expert. Be CONCISE and PRECISE. "
202
+ "Focus on CODE QUALITY over explanations. Use structured formats when requested. "
203
+ "Always check for syntax errors, security issues, and performance problems."
 
204
  )
205
 
206
  def make_request():
 
351
 
352
  return '\n\n'.join(filter(None, code_blocks))
353
 
354
+ def format_structured_explanation(response: str, code_output: str) -> str:
355
+ """Format the explanation in a structured, brief manner."""
356
+ # Extract key sections using regex
357
+ sections = {
358
+ "key_changes": "",
359
+ "critical_issues": "",
360
+ "warnings": ""
361
+ }
362
+
363
+ # Extract KEY CHANGES section
364
+ key_match = re.search(r"##\s*KEY CHANGES.*?\n((?:[-•]\s*.*?\n)+)", response, re.IGNORECASE | re.DOTALL)
365
+ if key_match:
366
+ sections["key_changes"] = key_match.group(1).strip()
367
+
368
+ # Extract CRITICAL ISSUES section
369
+ critical_match = re.search(r"##\s*CRITICAL ISSUES.*?\n((?:\d+\..*?\n)+)", response, re.IGNORECASE | re.DOTALL)
370
+ if critical_match:
371
+ sections["critical_issues"] = critical_match.group(1).strip()
372
+
373
+ # Extract WARNINGS section
374
+ warning_match = re.search(r"##\s*REMAINING WARNINGS.*?\n((?:[-•]\s*.*?\n)*)", response, re.IGNORECASE | re.DOTALL)
375
+ if warning_match:
376
+ sections["warnings"] = warning_match.group(1).strip()
377
+
378
+ # Build formatted explanation
379
+ formatted = "### Summary of Changes\n\n"
380
 
381
+ if sections["key_changes"]:
382
+ formatted += "**Key Changes:**\n" + sections["key_changes"] + "\n\n"
 
 
 
 
 
383
 
384
+ if sections["critical_issues"]:
385
+ formatted += "**Critical Issues Fixed:**\n" + sections["critical_issues"] + "\n\n"
386
 
387
+ if sections["warnings"]:
388
+ formatted += "**⚠️ Remaining Warnings:**\n" + sections["warnings"]
389
 
390
+ # If structured extraction failed, provide a brief summary
391
+ if not any(sections.values()):
392
+ # Fall back to a simple extraction
393
+ formatted = "### Code Correction Summary\n\n"
394
+ formatted += "The code has been corrected and optimized. "
395
+ formatted += "Check the code output for inline comments explaining specific changes.\n\n"
396
+ formatted += "For detailed analysis, see the Full Model Response."
397
+
398
+ return formatted.strip()
399
 
400
  def perform_skeptical_evaluation(code: str, context: str = "trigger") -> Dict[str, any]:
401
  """Perform skeptical evaluation of code looking for common issues."""
 
551
  # Perform skeptical evaluation
552
  evaluation = perform_skeptical_evaluation(trigger_code, "trigger")
553
 
554
+ # Build comprehensive prompt with structured output format
555
  prompt = f"""
556
+ Correct this Apex Trigger for B2B Lightning Experience migration. Be BRIEF and DIRECT.
557
+
558
+ ORIGINAL CODE:
559
+ ```apex
560
+ {trigger_code}
561
+ ```
562
+
563
+ DETECTED ISSUES:
564
+ - Syntax Errors: {len(syntax_issues)}
565
+ - Security Issues: {len(evaluation['security_concerns'])}
 
 
 
566
  - Performance Issues: {len(evaluation['performance_issues'])}
567
  - B2B Commerce Issues: {len(evaluation['b2b_commerce_issues'])}
568
 
569
+ PROVIDE EXACTLY THIS FORMAT:
570
+
571
+ ## CORRECTED CODE
572
  ```apex
573
+ [Put the complete corrected trigger here with inline comments for changes]
574
  ```
575
 
576
+ ## KEY CHANGES (bullet points only)
577
+ - [Change 1: Brief description]
578
+ - [Change 2: Brief description]
579
+ - [Maximum 7 bullet points]
580
+
581
+ ## CRITICAL ISSUES FIXED
582
+ 1. [Most important issue]: [One-line explanation]
583
+ 2. [Second issue]: [One-line explanation]
584
+ 3. [Third issue]: [One-line explanation]
585
+
586
+ ## REMAINING WARNINGS
587
+ - [Any issues that need manual review]
588
 
589
+ BE CONCISE. NO VERBOSE EXPLANATIONS. FOCUS ON CODE QUALITY.
590
  """
591
 
592
  if progress:
593
  progress(0.5, desc="Calling AI model...")
594
 
595
+ response = call_llm(model, prompt, temperature=0.2) # Even lower temperature for consistency
596
 
597
  if progress:
598
  progress(0.8, desc="Processing response...")
 
601
  code_output = extract_code_blocks(response)
602
 
603
  # Validate the corrected code
604
+ validation_warnings = []
605
  if code_output:
606
  corrected_valid, corrected_issues = validate_apex_syntax(code_output)
607
  if not corrected_valid:
608
+ error_count = len([i for i in corrected_issues if i["type"] == "error"])
609
+ warning_count = len([i for i in corrected_issues if i["type"] == "warning"])
610
+ validation_warnings.append(f"⚠️ Validation: {error_count} errors, {warning_count} warnings remain")
611
 
612
+ # Extract structured explanation
613
+ explanation = format_structured_explanation(response, code_output)
614
 
615
+ # Add validation warnings if any
616
+ if validation_warnings:
617
+ explanation = "\n".join(validation_warnings) + "\n\n" + explanation
618
+
619
+ # Add test case reference (brief)
620
+ explanation += "\n\n**Test Template:** Available in Full Response section"
621
 
622
  if progress:
623
  progress(1.0, desc="Complete!")
 
648
  evaluation = perform_skeptical_evaluation(cc_object_code, "object")
649
 
650
  prompt = f"""
651
+ Convert this CloudCraze Object to B2B Lightning Experience. Be BRIEF and PRECISE.
 
 
 
 
 
 
 
 
652
 
653
+ CLOUDCRAZE OBJECT:
654
  ```
655
  {cc_object_code}
656
  ```
657
 
658
+ PROVIDE EXACTLY THIS FORMAT:
659
+
660
+ ## B2B LEX OBJECT MAPPING
661
+ - Source: [CloudCraze object name]
662
+ - Target: [B2B LEX object name]
663
+ - Migration Complexity: [Low/Medium/High]
664
+
665
+ ## CONVERTED CODE
666
+ ```apex
667
+ [Complete B2B LEX implementation with inline comments]
668
+ ```
669
+
670
+ ## FIELD MAPPINGS (table format)
671
+ | CC Field | B2B Field | Type | Notes |
672
+ |----------|-----------|------|-------|
673
+ | field1 | newField1 | Text | Required |
674
+ | field2 | newField2 | Number | Optional |
675
+
676
+ ## MIGRATION STEPS
677
+ 1. [Step 1 - one line]
678
+ 2. [Step 2 - one line]
679
+ 3. [Maximum 5 steps]
680
+
681
+ ## DATA MIGRATION SCRIPT
682
+ ```apex
683
+ [Brief data migration code if needed, otherwise state "Not Required"]
684
+ ```
685
+
686
+ ## WARNINGS
687
+ - [Any manual steps or considerations]
688
+
689
+ BE CONCISE. FOCUS ON ACTIONABLE INFORMATION.
690
  """
691
 
692
  if progress:
693
  progress(0.5, desc="Calling AI model...")
694
 
695
+ response = call_llm(model, prompt, temperature=0.2)
696
 
697
  if progress:
698
  progress(0.8, desc="Processing response...")
699
 
700
  # Extract code and explanations
701
  code_output = extract_code_blocks(response)
 
702
 
703
+ # Extract structured explanation
704
+ explanation = format_object_conversion_explanation(response, code_output)
705
+
706
+ # Add brief test reference
707
+ explanation += "\n\n**Test Utilities:** See Full Response for test data creation utilities"
708
 
709
  if progress:
710
  progress(1.0, desc="Complete!")
 
822
  return fig
823
 
824
  def validate_apex_trigger(validation_model: str, original_code: str, corrected_code: str) -> str:
825
+ """Enhanced validation with skeptical evaluation and structured output."""
826
  if not validation_model or not original_code.strip() or not corrected_code.strip():
827
  return "Please provide all required inputs for validation."
828
 
 
831
  corr_valid, corr_issues = validate_apex_syntax(corrected_code)
832
 
833
  prompt = f"""
834
+ Validate this Apex trigger correction. Be CRITICAL but CONCISE.
835
 
836
+ ORIGINAL ({len(orig_issues)} issues detected):
837
  ```apex
838
  {original_code}
839
  ```
840
 
841
+ CORRECTED ({len(corr_issues)} issues detected):
842
  ```apex
843
  {corrected_code}
844
  ```
845
 
846
+ PROVIDE THIS EXACT JSON FORMAT:
847
+ ```json
848
+ {{
849
+ "quality_rating": [1-10],
850
+ "accuracy": [0.0-1.0],
851
+ "completeness": [0.0-1.0],
852
+ "best_practices_alignment": [0.0-1.0],
853
+ "syntax_validity": [0.0-1.0],
854
+ "security_score": [0.0-1.0],
855
+ "performance_score": [0.0-1.0],
856
+ "errors": [
857
+ "Error 1: [specific line/issue]",
858
+ "Error 2: [specific line/issue]"
859
+ ],
860
+ "warnings": [
861
+ "Warning 1: [potential issue]",
862
+ "Warning 2: [potential issue]"
863
+ ],
864
+ "suggestions": [
865
+ "Improvement 1: [actionable suggestion]",
866
+ "Improvement 2: [actionable suggestion]"
867
+ ]
868
+ }}
869
+ ```
870
 
871
+ SCORING CRITERIA:
872
+ - quality_rating: Overall code quality (1=terrible, 10=excellent)
873
+ - accuracy: Correctness of fixes (0=wrong, 1=perfect)
874
+ - completeness: All issues addressed (0=none, 1=all)
875
+ - best_practices_alignment: Follows Salesforce standards (0=poor, 1=excellent)
876
+ - syntax_validity: No syntax errors (0=many errors, 1=error-free)
877
+ - security_score: Security best practices (0=vulnerable, 1=secure)
878
+ - performance_score: Efficiency and scalability (0=poor, 1=optimal)
879
 
880
+ BE HARSH. FIND PROBLEMS. Maximum 3 items per category.
881
  """
882
 
883
+ return call_llm(validation_model, prompt, temperature=0.1) # Very low temperature for consistent JSON
884
 
885
  def validate_cc_object_conversion(validation_model: str, original_object: str, converted_object: str) -> str:
886
+ """Enhanced validation for CloudCraze object conversion with structured output."""
887
  if not validation_model or not original_object.strip() or not converted_object.strip():
888
  return "Please provide all required inputs for validation."
889
 
890
  prompt = f"""
891
+ Validate this CloudCraze to B2B LEX conversion. Be CRITICAL and BRIEF.
892
 
893
+ ORIGINAL CLOUDCRAZE:
894
  ```
895
  {original_object}
896
  ```
897
 
898
+ CONVERTED B2B LEX:
899
  ```
900
  {converted_object}
901
  ```
902
 
903
+ PROVIDE THIS EXACT JSON FORMAT:
904
+ ```json
905
+ {{
906
+ "quality_rating": [1-10],
907
+ "accuracy": [0.0-1.0],
908
+ "completeness": [0.0-1.0],
909
+ "best_practices_alignment": [0.0-1.0],
910
+ "syntax_validity": [0.0-1.0],
911
+ "security_score": [0.0-1.0],
912
+ "performance_score": [0.0-1.0],
913
+ "errors": [
914
+ "Missing field: [field_name]",
915
+ "Wrong mapping: [issue]"
916
+ ],
917
+ "warnings": [
918
+ "Data type mismatch: [field]",
919
+ "Custom logic not migrated: [what]"
920
+ ],
921
+ "suggestions": [
922
+ "Add validation for: [field]",
923
+ "Consider indexing: [field]"
924
+ ]
925
+ }}
926
+ ```
927
+
928
+ FOCUS ON:
929
+ 1. Missing field mappings
930
+ 2. Data type conversions
931
+ 3. Relationship integrity
932
+ 4. Custom field handling
933
+ 5. Performance at scale
934
+
935
+ BE HARSH. Maximum 3 items per category. Focus on REAL issues.
936
  """
937
 
938
+ return call_llm(validation_model, prompt, temperature=0.1)
939
 
940
  def get_theme_styles(theme_choice: str) -> Tuple[str, str, str, str]:
941
  """Get theme styles for different UI elements."""