delightfulrachel commited on
Commit
56455aa
Β·
verified Β·
1 Parent(s): c6beb28

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -106
app.py CHANGED
@@ -22,72 +22,64 @@ def correct_apex_trigger(model: str, trigger_code: str, progress=None) -> Tuple[
22
  """Correct Apex Trigger with skeptical evaluation."""
23
  if progress:
24
  progress(0.1, desc="Validating input...")
25
-
26
  # Input validation
27
  if not trigger_code.strip():
28
  return "Please provide Apex Trigger code to correct.", "", ""
29
-
30
  if len(trigger_code.strip()) < 50:
31
  return "Code too short to be a valid Apex trigger. Please provide complete code.", "", ""
32
-
33
  # Perform initial syntax check
34
  is_valid, syntax_issues = validate_apex_syntax(trigger_code)
35
-
36
  if progress:
37
  progress(0.3, desc="Analyzing code structure...")
38
-
39
  # Perform skeptical evaluation
40
  evaluation = perform_skeptical_evaluation(trigger_code, "trigger")
41
-
42
  # Build comprehensive prompt with structured output format
43
  prompt = f"""
44
  Correct this Apex Trigger for B2B Lightning Experience migration. Be BRIEF and DIRECT.
45
-
46
  ORIGINAL CODE:
47
  ```apex
48
  {trigger_code}
49
  ```
50
-
51
  DETECTED ISSUES:
52
  - Syntax Errors: {len(syntax_issues)}
53
  - Security Issues: {len(evaluation['security_concerns'])}
54
  - Performance Issues: {len(evaluation['performance_issues'])}
55
  - B2B Commerce Issues: {len(evaluation['b2b_commerce_issues'])}
56
-
57
  PROVIDE EXACTLY THIS FORMAT:
58
-
59
  ## CORRECTED CODE
60
  ```apex
61
  [Put the complete corrected trigger here with inline comments for changes]
62
  ```
63
-
64
  ## KEY CHANGES (bullet points only)
65
  - [Change 1: Brief description]
66
  - [Change 2: Brief description]
67
  - [Maximum 7 bullet points]
68
-
69
  ## CRITICAL ISSUES FIXED
70
  1. [Most important issue]: [One-line explanation]
71
  2. [Second issue]: [One-line explanation]
72
  3. [Third issue]: [One-line explanation]
73
-
74
  ## REMAINING WARNINGS
75
  - [Any issues that need manual review]
76
-
77
  BE CONCISE. NO VERBOSE EXPLANATIONS. FOCUS ON CODE QUALITY.
78
  """
79
 
80
  if progress:
81
  progress(0.5, desc="Calling AI model...")
82
-
83
  response = call_llm(model, prompt, temperature=0.2) # Even lower temperature for consistency
84
-
85
  if progress:
86
  progress(0.8, desc="Processing response...")
87
-
88
  # Extract code and explanations
89
  code_output = extract_code_blocks(response)
90
-
91
  # Validate the corrected code
92
  validation_warnings = []
93
  if code_output:
@@ -96,132 +88,120 @@ BE CONCISE. NO VERBOSE EXPLANATIONS. FOCUS ON CODE QUALITY.
96
  error_count = len([i for i in corrected_issues if i["type"] == "error"])
97
  warning_count = len([i for i in corrected_issues if i["type"] == "warning"])
98
  validation_warnings.append(f"⚠️ Validation: {error_count} errors, {warning_count} warnings remain")
99
-
100
  # Extract structured explanation
101
  explanation = format_structured_explanation(response, code_output)
102
-
103
  # Add validation warnings if any
104
  if validation_warnings:
105
  explanation = "\n".join(validation_warnings) + "\n\n" + explanation
106
-
107
  # Add test case reference (brief)
108
  explanation += "\n\n**Test Template:** Available in Full Response section"
109
-
110
  if progress:
111
  progress(1.0, desc="Complete!")
112
-
113
  return response, code_output, explanation
114
 
115
  def convert_cc_object(model: str, cc_object_code: str, progress=None) -> Tuple[str, str, str]:
116
  """Convert CloudCraze Object with skeptical evaluation."""
117
  if progress:
118
  progress(0.1, desc="Validating input...")
119
-
120
  # Input validation
121
  if not cc_object_code.strip():
122
  return "Please provide CloudCraze Object code to convert.", "", ""
123
-
124
  if len(cc_object_code.strip()) < 30:
125
  return "Code too short to be a valid CloudCraze object. Please provide complete code.", "", ""
126
-
127
  if progress:
128
  progress(0.3, desc="Analyzing CloudCraze structure...")
129
-
130
  # Check for CloudCraze patterns
131
  import re
132
  has_cc_pattern = bool(re.search(B2B_COMMERCE_PATTERNS["cloudcraze_reference"], cc_object_code))
133
  if not has_cc_pattern:
134
  logger.warning("No obvious CloudCraze patterns found in input")
135
-
136
  # Perform evaluation
137
  evaluation = perform_skeptical_evaluation(cc_object_code, "object")
138
-
139
  prompt = f"""
140
  Convert this CloudCraze Object to B2B Lightning Experience. Be BRIEF and PRECISE.
141
-
142
  CLOUDCRAZE OBJECT:
143
  ```
144
  {cc_object_code}
145
  ```
146
-
147
  PROVIDE EXACTLY THIS FORMAT:
148
-
149
  ## B2B LEX OBJECT MAPPING
150
  - Source: [CloudCraze object name]
151
  - Target: [B2B LEX object name]
152
  - Migration Complexity: [Low/Medium/High]
153
-
154
  ## CONVERTED CODE
155
  ```apex
156
  [Complete B2B LEX implementation with inline comments]
157
  ```
158
-
159
  ## FIELD MAPPINGS (table format)
160
  | CC Field | B2B Field | Type | Notes |
161
  |----------|-----------|------|-------|
162
  | field1 | newField1 | Text | Required |
163
  | field2 | newField2 | Number | Optional |
164
-
165
  ## MIGRATION STEPS
166
  1. [Step 1 - one line]
167
  2. [Step 2 - one line]
168
  3. [Maximum 5 steps]
169
-
170
  ## DATA MIGRATION SCRIPT
171
  ```apex
172
  [Brief data migration code if needed, otherwise state "Not Required"]
173
  ```
174
-
175
  ## WARNINGS
176
  - [Any manual steps or considerations]
177
-
178
  BE CONCISE. FOCUS ON ACTIONABLE INFORMATION.
179
  """
180
 
181
  if progress:
182
  progress(0.5, desc="Calling AI model...")
183
-
184
  response = call_llm(model, prompt, temperature=0.2)
185
-
186
  if progress:
187
  progress(0.8, desc="Processing response...")
188
-
189
  # Extract code and explanations
190
  code_output = extract_code_blocks(response)
191
-
192
  # Extract structured explanation
193
  explanation = format_object_conversion_explanation(response, code_output)
194
-
195
  # Add brief test reference
196
  explanation += "\n\n**Test Utilities:** See Full Response for test data creation utilities"
197
-
198
  if progress:
199
  progress(1.0, desc="Complete!")
200
-
201
  return response, code_output, explanation
202
 
203
  def validate_apex_trigger(validation_model: str, original_code: str, corrected_code: str) -> str:
204
  """Enhanced validation with skeptical evaluation and structured output."""
205
  if not validation_model or not original_code.strip() or not corrected_code.strip():
206
  return "Please provide all required inputs for validation."
207
-
208
  # Perform syntax validation on both
209
  orig_valid, orig_issues = validate_apex_syntax(original_code)
210
  corr_valid, corr_issues = validate_apex_syntax(corrected_code)
211
-
212
  prompt = f"""
213
  Validate this Apex trigger correction. Be CRITICAL but CONCISE.
214
-
215
  ORIGINAL ({len(orig_issues)} issues detected):
216
  ```apex
217
  {original_code}
218
  ```
219
-
220
  CORRECTED ({len(corr_issues)} issues detected):
221
  ```apex
222
  {corrected_code}
223
  ```
224
-
225
  PROVIDE THIS EXACT JSON FORMAT:
226
  ```json
227
  {{
@@ -246,7 +226,6 @@ PROVIDE THIS EXACT JSON FORMAT:
246
  ]
247
  }}
248
  ```
249
-
250
  SCORING CRITERIA:
251
  - quality_rating: Overall code quality (1=terrible, 10=excellent)
252
  - accuracy: Correctness of fixes (0=wrong, 1=perfect)
@@ -255,30 +234,26 @@ SCORING CRITERIA:
255
  - syntax_validity: No syntax errors (0=many errors, 1=error-free)
256
  - security_score: Security best practices (0=vulnerable, 1=secure)
257
  - performance_score: Efficiency and scalability (0=poor, 1=optimal)
258
-
259
  BE HARSH. FIND PROBLEMS. Maximum 3 items per category.
260
  """
261
-
262
  return call_llm(validation_model, prompt, temperature=0.1) # Very low temperature for consistent JSON
263
 
264
  def validate_cc_object_conversion(validation_model: str, original_object: str, converted_object: str) -> str:
265
  """Enhanced validation for CloudCraze object conversion with structured output."""
266
  if not validation_model or not original_object.strip() or not converted_object.strip():
267
  return "Please provide all required inputs for validation."
268
-
269
  prompt = f"""
270
  Validate this CloudCraze to B2B LEX conversion. Be CRITICAL and BRIEF.
271
-
272
  ORIGINAL CLOUDCRAZE:
273
  ```
274
  {original_object}
275
  ```
276
-
277
  CONVERTED B2B LEX:
278
  ```
279
  {converted_object}
280
  ```
281
-
282
  PROVIDE THIS EXACT JSON FORMAT:
283
  ```json
284
  {{
@@ -303,24 +278,22 @@ PROVIDE THIS EXACT JSON FORMAT:
303
  ]
304
  }}
305
  ```
306
-
307
  FOCUS ON:
308
  1. Missing field mappings
309
  2. Data type conversions
310
  3. Relationship integrity
311
  4. Custom field handling
312
  5. Performance at scale
313
-
314
  BE HARSH. Maximum 3 items per category. Focus on REAL issues.
315
  """
316
-
317
  return call_llm(validation_model, prompt, temperature=0.1)
318
 
319
  def create_enhanced_radar_chart(metrics: Optional[Dict[str, float]]) -> Optional[object]:
320
  """Create an enhanced radar chart with more metrics."""
321
  if not metrics:
322
  return None
323
-
324
  # Create data for the radar chart
325
  categories = [
326
  "Quality",
@@ -331,7 +304,7 @@ def create_enhanced_radar_chart(metrics: Optional[Dict[str, float]]) -> Optional
331
  "Security",
332
  "Performance"
333
  ]
334
-
335
  values = [
336
  metrics.get("quality_rating", 0) / 10, # Normalize to 0-1 scale
337
  metrics.get("accuracy", 0),
@@ -341,13 +314,13 @@ def create_enhanced_radar_chart(metrics: Optional[Dict[str, float]]) -> Optional
341
  metrics.get("security_score", 0),
342
  metrics.get("performance_score", 0)
343
  ]
344
-
345
  # Create a DataFrame for plotting
346
  df = pd.DataFrame({
347
  'Category': categories,
348
  'Value': values
349
  })
350
-
351
  # Create the radar chart
352
  fig = px.line_polar(
353
  df, r='Value', theta='Category', line_close=True,
@@ -364,7 +337,7 @@ def create_enhanced_radar_chart(metrics: Optional[Dict[str, float]]) -> Optional
364
  showlegend=False,
365
  height=400
366
  )
367
-
368
  return fig
369
 
370
  def get_theme_styles(theme_choice: str) -> Tuple[str, str, str, str]:
@@ -383,7 +356,7 @@ def get_theme_styles(theme_choice: str) -> Tuple[str, str, str, str]:
383
  "error": "background-color: #ffe4e6; color: #d73a49; padding: 10px; border-radius: 5px; border: 1px solid #d73a49;"
384
  }
385
  }
386
-
387
  theme = themes.get(theme_choice, themes["Light"])
388
  return (theme["explanation"], theme["code"], theme["explanation"], theme["code"])
389
 
@@ -393,11 +366,11 @@ def trigger_correction_wrapper(model, code):
393
  try:
394
  if not model or not code.strip():
395
  return "Please select a model and provide code.", "", "Please provide valid inputs."
396
-
397
  # Create dummy progress function since Gradio progress doesn't work in lambda
398
  def dummy_progress(value, desc=""):
399
  pass
400
-
401
  return correct_apex_trigger(model, code, progress=dummy_progress)
402
  except Exception as e:
403
  logger.error(f"Trigger correction error: {str(e)}")
@@ -409,10 +382,10 @@ def object_conversion_wrapper(model, code):
409
  try:
410
  if not model or not code.strip():
411
  return "Please select a model and provide code.", "", "Please provide valid inputs."
412
-
413
  def dummy_progress(value, desc=""):
414
  pass
415
-
416
  return convert_cc_object(model, code, progress=dummy_progress)
417
  except Exception as e:
418
  logger.error(f"Object conversion error: {str(e)}")
@@ -424,7 +397,7 @@ def validate_and_chart_trigger(model, original, corrected):
424
  try:
425
  if not model or not original.strip() or not corrected.strip():
426
  return "Please provide all required inputs for validation.", None
427
-
428
  validation_text = validate_apex_trigger(model, original, corrected)
429
  metrics = extract_validation_metrics(validation_text)
430
  chart = create_enhanced_radar_chart(metrics) if metrics else None
@@ -438,7 +411,7 @@ def validate_and_chart_object(model, original, converted):
438
  try:
439
  if not model or not original.strip() or not converted.strip():
440
  return "Please provide all required inputs for validation.", None
441
-
442
  validation_text = validate_cc_object_conversion(model, original, converted)
443
  metrics = extract_validation_metrics(validation_text)
444
  chart = create_enhanced_radar_chart(metrics) if metrics else None
@@ -450,9 +423,9 @@ def validate_and_chart_object(model, original, converted):
450
  def main():
451
  """Main application entry point."""
452
  with gr.Blocks(
453
- title="Salesforce B2B Commerce Migration Assistant",
454
- theme=gr.themes.Soft(primary_hue="blue"),
455
- css="""
456
  .gradio-container {
457
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
458
  }
@@ -467,7 +440,7 @@ def main():
467
  }
468
  """
469
  ) as app:
470
-
471
  gr.Markdown("# πŸš€ Salesforce B2B Commerce Migration Assistant")
472
  gr.Markdown("Advanced tool for migrating CloudCraze code to B2B Lightning Experience with skeptical AI validation.")
473
 
@@ -481,7 +454,7 @@ def main():
481
  label="Select Primary AI Model for Conversion",
482
  info="This model performs the initial code conversion"
483
  )
484
-
485
  with gr.Column():
486
  gr.Markdown("### πŸ” Validation Model")
487
  validation_model_dropdown = gr.Dropdown(
@@ -501,21 +474,21 @@ def main():
501
  label="Apex Trigger Code",
502
  elem_classes="code-input"
503
  )
504
-
505
  with gr.Row():
506
  trigger_button = gr.Button("πŸ”§ Correct & Optimize", variant="primary", size="lg")
507
  copy_code_button = gr.Button("πŸ“‹ Copy Code", variant="secondary")
508
-
509
  # Progress indicator
510
  trigger_progress = gr.Textbox(label="Progress", visible=False)
511
-
512
  with gr.Accordion("πŸ“„ Full Model Response", open=False):
513
  trigger_full_response = gr.Textbox(
514
  lines=20,
515
  label="Full Model Response",
516
  interactive=False
517
  )
518
-
519
  with gr.Row():
520
  with gr.Column():
521
  trigger_explanation = gr.Textbox(
@@ -525,7 +498,7 @@ def main():
525
  interactive=False,
526
  elem_id="trigger_explanation"
527
  )
528
-
529
  with gr.Column():
530
  trigger_code_output = gr.Code(
531
  language="python", # Using python highlighting as java is not supported
@@ -533,7 +506,7 @@ def main():
533
  value="// Corrected Apex code will appear here",
534
  elem_id="trigger_code_output"
535
  )
536
-
537
  gr.Markdown("### 🎯 Validation Results")
538
  with gr.Row():
539
  with gr.Column(scale=2):
@@ -546,9 +519,9 @@ def main():
546
  )
547
  with gr.Column(scale=1):
548
  trigger_chart = gr.Plot(label="πŸ“Š Validation Metrics")
549
-
550
  validate_trigger_button = gr.Button("πŸ” Validate Correction", variant="secondary", size="lg")
551
-
552
  # Wire up functionality - INSIDE the main function where UI elements are defined
553
  trigger_button.click(
554
  fn=trigger_correction_wrapper,
@@ -556,24 +529,24 @@ def main():
556
  outputs=[trigger_full_response, trigger_code_output, trigger_explanation],
557
  show_progress=True
558
  )
559
-
560
  validate_trigger_button.click(
561
  fn=validate_and_chart_trigger,
562
  inputs=[validation_model_dropdown, trigger_input, trigger_code_output],
563
  outputs=[trigger_validation_output, trigger_chart],
564
  show_progress=True
565
  )
566
-
567
  copy_code_button.click(
568
  fn=lambda: gr.Info("Code copied! Use Ctrl+C/Cmd+C if automatic copy fails."),
569
  inputs=[],
570
  outputs=[]
571
  )
572
-
573
  with gr.Row():
574
  trigger_clear = gr.Button("πŸ—‘οΈ Clear Input")
575
  trigger_clear.click(lambda: "", [], trigger_input)
576
-
577
  results_clear = gr.Button("🧹 Clear Results")
578
  results_clear.click(
579
  lambda: ["", "", "", "", None],
@@ -591,21 +564,21 @@ def main():
591
  label="CloudCraze Object Code",
592
  elem_classes="code-input"
593
  )
594
-
595
  with gr.Row():
596
  object_button = gr.Button("πŸ”„ Convert Object", variant="primary", size="lg")
597
  object_copy_code_button = gr.Button("πŸ“‹ Copy Code", variant="secondary")
598
-
599
  # Progress indicator
600
  object_progress = gr.Textbox(label="Progress", visible=False)
601
-
602
  with gr.Accordion("πŸ“„ Full Model Response", open=False):
603
  object_full_response = gr.Textbox(
604
  lines=20,
605
  label="Full Model Response",
606
  interactive=False
607
  )
608
-
609
  with gr.Row():
610
  with gr.Column():
611
  object_explanation = gr.Textbox(
@@ -615,7 +588,7 @@ def main():
615
  interactive=False,
616
  elem_id="object_explanation"
617
  )
618
-
619
  with gr.Column():
620
  object_code_output = gr.Code(
621
  language="python", # Using python highlighting as java is not supported
@@ -623,7 +596,7 @@ def main():
623
  value="// Converted B2B Lightning Experience code will appear here",
624
  elem_id="object_code_output"
625
  )
626
-
627
  gr.Markdown("### 🎯 Validation Results")
628
  with gr.Row():
629
  with gr.Column(scale=2):
@@ -636,9 +609,9 @@ def main():
636
  )
637
  with gr.Column(scale=1):
638
  object_chart = gr.Plot(label="πŸ“Š Validation Metrics")
639
-
640
  validate_object_button = gr.Button("πŸ” Validate Conversion", variant="secondary", size="lg")
641
-
642
  # Wire up functionality - INSIDE the main function where UI elements are defined
643
  object_button.click(
644
  fn=object_conversion_wrapper,
@@ -646,24 +619,24 @@ def main():
646
  outputs=[object_full_response, object_code_output, object_explanation],
647
  show_progress=True
648
  )
649
-
650
  validate_object_button.click(
651
  fn=validate_and_chart_object,
652
  inputs=[validation_model_dropdown, object_input, object_code_output],
653
  outputs=[object_validation_output, object_chart],
654
  show_progress=True
655
  )
656
-
657
  object_copy_code_button.click(
658
  fn=lambda: gr.Info("Code copied! Use Ctrl+C/Cmd+C if automatic copy fails."),
659
  inputs=[],
660
  outputs=[]
661
  )
662
-
663
  with gr.Row():
664
  object_clear = gr.Button("πŸ—‘οΈ Clear Input")
665
  object_clear.click(lambda: "", [], object_input)
666
-
667
  object_results_clear = gr.Button("🧹 Clear Results")
668
  object_results_clear.click(
669
  lambda: ["", "", "", "", None],
@@ -674,17 +647,17 @@ def main():
674
  # UI Preferences
675
  with gr.Accordion("βš™οΈ UI Preferences", open=False):
676
  theme_radio = gr.Radio(
677
- label="🎨 Theme",
678
- choices=["Light", "Dark"],
679
  value="Light"
680
  )
681
-
682
  # Comment out theme functionality for now to avoid conflicts
683
  # theme_radio.change(
684
  # fn=get_theme_styles,
685
  # inputs=[theme_radio],
686
  # outputs=[
687
- # trigger_explanation,
688
  # trigger_code_output,
689
  # object_explanation,
690
  # object_code_output
@@ -712,4 +685,4 @@ def main():
712
  app.launch()
713
 
714
  if __name__ == "__main__":
715
- main()
 
22
  """Correct Apex Trigger with skeptical evaluation."""
23
  if progress:
24
  progress(0.1, desc="Validating input...")
25
+
26
  # Input validation
27
  if not trigger_code.strip():
28
  return "Please provide Apex Trigger code to correct.", "", ""
29
+
30
  if len(trigger_code.strip()) < 50:
31
  return "Code too short to be a valid Apex trigger. Please provide complete code.", "", ""
32
+
33
  # Perform initial syntax check
34
  is_valid, syntax_issues = validate_apex_syntax(trigger_code)
35
+
36
  if progress:
37
  progress(0.3, desc="Analyzing code structure...")
38
+
39
  # Perform skeptical evaluation
40
  evaluation = perform_skeptical_evaluation(trigger_code, "trigger")
41
+
42
  # Build comprehensive prompt with structured output format
43
  prompt = f"""
44
  Correct this Apex Trigger for B2B Lightning Experience migration. Be BRIEF and DIRECT.
 
45
  ORIGINAL CODE:
46
  ```apex
47
  {trigger_code}
48
  ```
 
49
  DETECTED ISSUES:
50
  - Syntax Errors: {len(syntax_issues)}
51
  - Security Issues: {len(evaluation['security_concerns'])}
52
  - Performance Issues: {len(evaluation['performance_issues'])}
53
  - B2B Commerce Issues: {len(evaluation['b2b_commerce_issues'])}
 
54
  PROVIDE EXACTLY THIS FORMAT:
 
55
  ## CORRECTED CODE
56
  ```apex
57
  [Put the complete corrected trigger here with inline comments for changes]
58
  ```
 
59
  ## KEY CHANGES (bullet points only)
60
  - [Change 1: Brief description]
61
  - [Change 2: Brief description]
62
  - [Maximum 7 bullet points]
 
63
  ## CRITICAL ISSUES FIXED
64
  1. [Most important issue]: [One-line explanation]
65
  2. [Second issue]: [One-line explanation]
66
  3. [Third issue]: [One-line explanation]
 
67
  ## REMAINING WARNINGS
68
  - [Any issues that need manual review]
 
69
  BE CONCISE. NO VERBOSE EXPLANATIONS. FOCUS ON CODE QUALITY.
70
  """
71
 
72
  if progress:
73
  progress(0.5, desc="Calling AI model...")
74
+
75
  response = call_llm(model, prompt, temperature=0.2) # Even lower temperature for consistency
76
+
77
  if progress:
78
  progress(0.8, desc="Processing response...")
79
+
80
  # Extract code and explanations
81
  code_output = extract_code_blocks(response)
82
+
83
  # Validate the corrected code
84
  validation_warnings = []
85
  if code_output:
 
88
  error_count = len([i for i in corrected_issues if i["type"] == "error"])
89
  warning_count = len([i for i in corrected_issues if i["type"] == "warning"])
90
  validation_warnings.append(f"⚠️ Validation: {error_count} errors, {warning_count} warnings remain")
91
+
92
  # Extract structured explanation
93
  explanation = format_structured_explanation(response, code_output)
94
+
95
  # Add validation warnings if any
96
  if validation_warnings:
97
  explanation = "\n".join(validation_warnings) + "\n\n" + explanation
98
+
99
  # Add test case reference (brief)
100
  explanation += "\n\n**Test Template:** Available in Full Response section"
101
+
102
  if progress:
103
  progress(1.0, desc="Complete!")
104
+
105
  return response, code_output, explanation
106
 
107
  def convert_cc_object(model: str, cc_object_code: str, progress=None) -> Tuple[str, str, str]:
108
  """Convert CloudCraze Object with skeptical evaluation."""
109
  if progress:
110
  progress(0.1, desc="Validating input...")
111
+
112
  # Input validation
113
  if not cc_object_code.strip():
114
  return "Please provide CloudCraze Object code to convert.", "", ""
115
+
116
  if len(cc_object_code.strip()) < 30:
117
  return "Code too short to be a valid CloudCraze object. Please provide complete code.", "", ""
118
+
119
  if progress:
120
  progress(0.3, desc="Analyzing CloudCraze structure...")
121
+
122
  # Check for CloudCraze patterns
123
  import re
124
  has_cc_pattern = bool(re.search(B2B_COMMERCE_PATTERNS["cloudcraze_reference"], cc_object_code))
125
  if not has_cc_pattern:
126
  logger.warning("No obvious CloudCraze patterns found in input")
127
+
128
  # Perform evaluation
129
  evaluation = perform_skeptical_evaluation(cc_object_code, "object")
130
+
131
  prompt = f"""
132
  Convert this CloudCraze Object to B2B Lightning Experience. Be BRIEF and PRECISE.
 
133
  CLOUDCRAZE OBJECT:
134
  ```
135
  {cc_object_code}
136
  ```
 
137
  PROVIDE EXACTLY THIS FORMAT:
 
138
  ## B2B LEX OBJECT MAPPING
139
  - Source: [CloudCraze object name]
140
  - Target: [B2B LEX object name]
141
  - Migration Complexity: [Low/Medium/High]
 
142
  ## CONVERTED CODE
143
  ```apex
144
  [Complete B2B LEX implementation with inline comments]
145
  ```
 
146
  ## FIELD MAPPINGS (table format)
147
  | CC Field | B2B Field | Type | Notes |
148
  |----------|-----------|------|-------|
149
  | field1 | newField1 | Text | Required |
150
  | field2 | newField2 | Number | Optional |
 
151
  ## MIGRATION STEPS
152
  1. [Step 1 - one line]
153
  2. [Step 2 - one line]
154
  3. [Maximum 5 steps]
 
155
  ## DATA MIGRATION SCRIPT
156
  ```apex
157
  [Brief data migration code if needed, otherwise state "Not Required"]
158
  ```
 
159
  ## WARNINGS
160
  - [Any manual steps or considerations]
 
161
  BE CONCISE. FOCUS ON ACTIONABLE INFORMATION.
162
  """
163
 
164
  if progress:
165
  progress(0.5, desc="Calling AI model...")
166
+
167
  response = call_llm(model, prompt, temperature=0.2)
168
+
169
  if progress:
170
  progress(0.8, desc="Processing response...")
171
+
172
  # Extract code and explanations
173
  code_output = extract_code_blocks(response)
174
+
175
  # Extract structured explanation
176
  explanation = format_object_conversion_explanation(response, code_output)
177
+
178
  # Add brief test reference
179
  explanation += "\n\n**Test Utilities:** See Full Response for test data creation utilities"
180
+
181
  if progress:
182
  progress(1.0, desc="Complete!")
183
+
184
  return response, code_output, explanation
185
 
186
  def validate_apex_trigger(validation_model: str, original_code: str, corrected_code: str) -> str:
187
  """Enhanced validation with skeptical evaluation and structured output."""
188
  if not validation_model or not original_code.strip() or not corrected_code.strip():
189
  return "Please provide all required inputs for validation."
190
+
191
  # Perform syntax validation on both
192
  orig_valid, orig_issues = validate_apex_syntax(original_code)
193
  corr_valid, corr_issues = validate_apex_syntax(corrected_code)
194
+
195
  prompt = f"""
196
  Validate this Apex trigger correction. Be CRITICAL but CONCISE.
 
197
  ORIGINAL ({len(orig_issues)} issues detected):
198
  ```apex
199
  {original_code}
200
  ```
 
201
  CORRECTED ({len(corr_issues)} issues detected):
202
  ```apex
203
  {corrected_code}
204
  ```
 
205
  PROVIDE THIS EXACT JSON FORMAT:
206
  ```json
207
  {{
 
226
  ]
227
  }}
228
  ```
 
229
  SCORING CRITERIA:
230
  - quality_rating: Overall code quality (1=terrible, 10=excellent)
231
  - accuracy: Correctness of fixes (0=wrong, 1=perfect)
 
234
  - syntax_validity: No syntax errors (0=many errors, 1=error-free)
235
  - security_score: Security best practices (0=vulnerable, 1=secure)
236
  - performance_score: Efficiency and scalability (0=poor, 1=optimal)
 
237
  BE HARSH. FIND PROBLEMS. Maximum 3 items per category.
238
  """
239
+
240
  return call_llm(validation_model, prompt, temperature=0.1) # Very low temperature for consistent JSON
241
 
242
  def validate_cc_object_conversion(validation_model: str, original_object: str, converted_object: str) -> str:
243
  """Enhanced validation for CloudCraze object conversion with structured output."""
244
  if not validation_model or not original_object.strip() or not converted_object.strip():
245
  return "Please provide all required inputs for validation."
246
+
247
  prompt = f"""
248
  Validate this CloudCraze to B2B LEX conversion. Be CRITICAL and BRIEF.
 
249
  ORIGINAL CLOUDCRAZE:
250
  ```
251
  {original_object}
252
  ```
 
253
  CONVERTED B2B LEX:
254
  ```
255
  {converted_object}
256
  ```
 
257
  PROVIDE THIS EXACT JSON FORMAT:
258
  ```json
259
  {{
 
278
  ]
279
  }}
280
  ```
 
281
  FOCUS ON:
282
  1. Missing field mappings
283
  2. Data type conversions
284
  3. Relationship integrity
285
  4. Custom field handling
286
  5. Performance at scale
 
287
  BE HARSH. Maximum 3 items per category. Focus on REAL issues.
288
  """
289
+
290
  return call_llm(validation_model, prompt, temperature=0.1)
291
 
292
  def create_enhanced_radar_chart(metrics: Optional[Dict[str, float]]) -> Optional[object]:
293
  """Create an enhanced radar chart with more metrics."""
294
  if not metrics:
295
  return None
296
+
297
  # Create data for the radar chart
298
  categories = [
299
  "Quality",
 
304
  "Security",
305
  "Performance"
306
  ]
307
+
308
  values = [
309
  metrics.get("quality_rating", 0) / 10, # Normalize to 0-1 scale
310
  metrics.get("accuracy", 0),
 
314
  metrics.get("security_score", 0),
315
  metrics.get("performance_score", 0)
316
  ]
317
+
318
  # Create a DataFrame for plotting
319
  df = pd.DataFrame({
320
  'Category': categories,
321
  'Value': values
322
  })
323
+
324
  # Create the radar chart
325
  fig = px.line_polar(
326
  df, r='Value', theta='Category', line_close=True,
 
337
  showlegend=False,
338
  height=400
339
  )
340
+
341
  return fig
342
 
343
  def get_theme_styles(theme_choice: str) -> Tuple[str, str, str, str]:
 
356
  "error": "background-color: #ffe4e6; color: #d73a49; padding: 10px; border-radius: 5px; border: 1px solid #d73a49;"
357
  }
358
  }
359
+
360
  theme = themes.get(theme_choice, themes["Light"])
361
  return (theme["explanation"], theme["code"], theme["explanation"], theme["code"])
362
 
 
366
  try:
367
  if not model or not code.strip():
368
  return "Please select a model and provide code.", "", "Please provide valid inputs."
369
+
370
  # Create dummy progress function since Gradio progress doesn't work in lambda
371
  def dummy_progress(value, desc=""):
372
  pass
373
+
374
  return correct_apex_trigger(model, code, progress=dummy_progress)
375
  except Exception as e:
376
  logger.error(f"Trigger correction error: {str(e)}")
 
382
  try:
383
  if not model or not code.strip():
384
  return "Please select a model and provide code.", "", "Please provide valid inputs."
385
+
386
  def dummy_progress(value, desc=""):
387
  pass
388
+
389
  return convert_cc_object(model, code, progress=dummy_progress)
390
  except Exception as e:
391
  logger.error(f"Object conversion error: {str(e)}")
 
397
  try:
398
  if not model or not original.strip() or not corrected.strip():
399
  return "Please provide all required inputs for validation.", None
400
+
401
  validation_text = validate_apex_trigger(model, original, corrected)
402
  metrics = extract_validation_metrics(validation_text)
403
  chart = create_enhanced_radar_chart(metrics) if metrics else None
 
411
  try:
412
  if not model or not original.strip() or not converted.strip():
413
  return "Please provide all required inputs for validation.", None
414
+
415
  validation_text = validate_cc_object_conversion(model, original, converted)
416
  metrics = extract_validation_metrics(validation_text)
417
  chart = create_enhanced_radar_chart(metrics) if metrics else None
 
423
  def main():
424
  """Main application entry point."""
425
  with gr.Blocks(
426
+ title="Salesforce B2B Commerce Migration Assistant",
427
+ theme=gr.themes.Soft(primary_hue="blue"),
428
+ css="""
429
  .gradio-container {
430
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
431
  }
 
440
  }
441
  """
442
  ) as app:
443
+
444
  gr.Markdown("# πŸš€ Salesforce B2B Commerce Migration Assistant")
445
  gr.Markdown("Advanced tool for migrating CloudCraze code to B2B Lightning Experience with skeptical AI validation.")
446
 
 
454
  label="Select Primary AI Model for Conversion",
455
  info="This model performs the initial code conversion"
456
  )
457
+
458
  with gr.Column():
459
  gr.Markdown("### πŸ” Validation Model")
460
  validation_model_dropdown = gr.Dropdown(
 
474
  label="Apex Trigger Code",
475
  elem_classes="code-input"
476
  )
477
+
478
  with gr.Row():
479
  trigger_button = gr.Button("πŸ”§ Correct & Optimize", variant="primary", size="lg")
480
  copy_code_button = gr.Button("πŸ“‹ Copy Code", variant="secondary")
481
+
482
  # Progress indicator
483
  trigger_progress = gr.Textbox(label="Progress", visible=False)
484
+
485
  with gr.Accordion("πŸ“„ Full Model Response", open=False):
486
  trigger_full_response = gr.Textbox(
487
  lines=20,
488
  label="Full Model Response",
489
  interactive=False
490
  )
491
+
492
  with gr.Row():
493
  with gr.Column():
494
  trigger_explanation = gr.Textbox(
 
498
  interactive=False,
499
  elem_id="trigger_explanation"
500
  )
501
+
502
  with gr.Column():
503
  trigger_code_output = gr.Code(
504
  language="python", # Using python highlighting as java is not supported
 
506
  value="// Corrected Apex code will appear here",
507
  elem_id="trigger_code_output"
508
  )
509
+
510
  gr.Markdown("### 🎯 Validation Results")
511
  with gr.Row():
512
  with gr.Column(scale=2):
 
519
  )
520
  with gr.Column(scale=1):
521
  trigger_chart = gr.Plot(label="πŸ“Š Validation Metrics")
522
+
523
  validate_trigger_button = gr.Button("πŸ” Validate Correction", variant="secondary", size="lg")
524
+
525
  # Wire up functionality - INSIDE the main function where UI elements are defined
526
  trigger_button.click(
527
  fn=trigger_correction_wrapper,
 
529
  outputs=[trigger_full_response, trigger_code_output, trigger_explanation],
530
  show_progress=True
531
  )
532
+
533
  validate_trigger_button.click(
534
  fn=validate_and_chart_trigger,
535
  inputs=[validation_model_dropdown, trigger_input, trigger_code_output],
536
  outputs=[trigger_validation_output, trigger_chart],
537
  show_progress=True
538
  )
539
+
540
  copy_code_button.click(
541
  fn=lambda: gr.Info("Code copied! Use Ctrl+C/Cmd+C if automatic copy fails."),
542
  inputs=[],
543
  outputs=[]
544
  )
545
+
546
  with gr.Row():
547
  trigger_clear = gr.Button("πŸ—‘οΈ Clear Input")
548
  trigger_clear.click(lambda: "", [], trigger_input)
549
+
550
  results_clear = gr.Button("🧹 Clear Results")
551
  results_clear.click(
552
  lambda: ["", "", "", "", None],
 
564
  label="CloudCraze Object Code",
565
  elem_classes="code-input"
566
  )
567
+
568
  with gr.Row():
569
  object_button = gr.Button("πŸ”„ Convert Object", variant="primary", size="lg")
570
  object_copy_code_button = gr.Button("πŸ“‹ Copy Code", variant="secondary")
571
+
572
  # Progress indicator
573
  object_progress = gr.Textbox(label="Progress", visible=False)
574
+
575
  with gr.Accordion("πŸ“„ Full Model Response", open=False):
576
  object_full_response = gr.Textbox(
577
  lines=20,
578
  label="Full Model Response",
579
  interactive=False
580
  )
581
+
582
  with gr.Row():
583
  with gr.Column():
584
  object_explanation = gr.Textbox(
 
588
  interactive=False,
589
  elem_id="object_explanation"
590
  )
591
+
592
  with gr.Column():
593
  object_code_output = gr.Code(
594
  language="python", # Using python highlighting as java is not supported
 
596
  value="// Converted B2B Lightning Experience code will appear here",
597
  elem_id="object_code_output"
598
  )
599
+
600
  gr.Markdown("### 🎯 Validation Results")
601
  with gr.Row():
602
  with gr.Column(scale=2):
 
609
  )
610
  with gr.Column(scale=1):
611
  object_chart = gr.Plot(label="πŸ“Š Validation Metrics")
612
+
613
  validate_object_button = gr.Button("πŸ” Validate Conversion", variant="secondary", size="lg")
614
+
615
  # Wire up functionality - INSIDE the main function where UI elements are defined
616
  object_button.click(
617
  fn=object_conversion_wrapper,
 
619
  outputs=[object_full_response, object_code_output, object_explanation],
620
  show_progress=True
621
  )
622
+
623
  validate_object_button.click(
624
  fn=validate_and_chart_object,
625
  inputs=[validation_model_dropdown, object_input, object_code_output],
626
  outputs=[object_validation_output, object_chart],
627
  show_progress=True
628
  )
629
+
630
  object_copy_code_button.click(
631
  fn=lambda: gr.Info("Code copied! Use Ctrl+C/Cmd+C if automatic copy fails."),
632
  inputs=[],
633
  outputs=[]
634
  )
635
+
636
  with gr.Row():
637
  object_clear = gr.Button("πŸ—‘οΈ Clear Input")
638
  object_clear.click(lambda: "", [], object_input)
639
+
640
  object_results_clear = gr.Button("🧹 Clear Results")
641
  object_results_clear.click(
642
  lambda: ["", "", "", "", None],
 
647
  # UI Preferences
648
  with gr.Accordion("βš™οΈ UI Preferences", open=False):
649
  theme_radio = gr.Radio(
650
+ label="🎨 Theme",
651
+ choices=["Light", "Dark"],
652
  value="Light"
653
  )
654
+
655
  # Comment out theme functionality for now to avoid conflicts
656
  # theme_radio.change(
657
  # fn=get_theme_styles,
658
  # inputs=[theme_radio],
659
  # outputs=[
660
+ # trigger_explanation,
661
  # trigger_code_output,
662
  # object_explanation,
663
  # object_code_output
 
685
  app.launch()
686
 
687
  if __name__ == "__main__":
688
+ main()