delightfulrachel commited on
Commit
91d2a21
·
verified ·
1 Parent(s): f8230de

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +224 -38
app.py CHANGED
@@ -5,6 +5,7 @@ import requests
5
  import json
6
  import plotly.express as px
7
  import pandas as pd
 
8
 
9
  # Model options for dropdown with both Together AI and Anthropic models
10
  together_models = [
@@ -133,9 +134,59 @@ def call_llm(model, prompt, temperature=0.7, max_tokens=1500):
133
  else:
134
  return f"Error: Unknown provider for model {model}"
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  def correct_apex_trigger(model, trigger_code):
137
  if not trigger_code.strip():
138
- return "Please provide Apex Trigger code to correct."
139
  prompt = f"""
140
  Please analyze and correct the following Apex Trigger code for migration from CloudCraze to B2B Lightning Experience.
141
  Identify any issues, optimize it according to best practices, and provide the corrected code.
@@ -144,13 +195,19 @@ Identify any issues, optimize it according to best practices, and provide the co
144
  {trigger_code}
145
  ```
146
 
147
- Please return the corrected code with explanations of changes.
148
  """
149
- return call_llm(model, prompt)
 
 
 
 
 
 
150
 
151
  def convert_cc_object(model, cc_object_code):
152
  if not cc_object_code.strip():
153
- return "Please provide CloudCraze Object code to convert."
154
  prompt = f"""
155
  Please convert the following CloudCraze Object code to B2B Lightning Experience format.
156
  Identify the corresponding B2B LEx system object, map fields, and provide the full definition.
@@ -162,10 +219,16 @@ Identify the corresponding B2B LEx system object, map fields, and provide the fu
162
  Return:
163
  1. Equivalent B2B LEx object name
164
  2. Field mappings
165
- 3. Full implementation code
166
  4. Additional steps if needed
167
  """
168
- return call_llm(model, prompt)
 
 
 
 
 
 
169
 
170
  def validate_apex_trigger(validation_model, original_code, corrected_code):
171
  if not validation_model or not original_code.strip() or not corrected_code.strip():
@@ -292,8 +355,22 @@ def create_radar_chart(metrics):
292
 
293
  return fig
294
 
 
 
 
 
 
 
 
 
 
 
 
295
  def main():
296
- with gr.Blocks(title="Salesforce B2B Commerce Migration Assistant") as app:
 
 
 
297
  gr.Markdown("# Salesforce B2B Commerce Migration Assistant")
298
  gr.Markdown("This tool helps migrate CloudCraze code to B2B Lightning Experience.")
299
 
@@ -325,18 +402,35 @@ def main():
325
  placeholder="Paste Apex Trigger code here...",
326
  label="Apex Trigger Code"
327
  )
328
- trigger_output = gr.Textbox(
329
- lines=15,
330
- label="Corrected Apex Trigger",
331
- interactive=True
332
- )
333
- trigger_button = gr.Button("Correct Apex Trigger")
334
- trigger_button.click(
335
- fn=correct_apex_trigger,
336
- inputs=[primary_model_dropdown, trigger_input],
337
- outputs=trigger_output,
338
- show_progress=True
339
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
 
341
  gr.Markdown("### Validation Results")
342
  with gr.Row():
@@ -358,22 +452,48 @@ def main():
358
  chart = create_radar_chart(metrics) if metrics else None
359
  return validation_text, chart
360
 
 
 
 
 
 
 
 
 
361
  validate_trigger_button.click(
362
  fn=validate_and_chart_trigger,
363
- inputs=[validation_model_dropdown, trigger_input, trigger_output],
364
  outputs=[trigger_validation_output, trigger_chart],
365
  show_progress=True
366
  )
367
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  with gr.Row():
369
  trigger_clear = gr.Button("Clear Input")
370
  trigger_clear.click(lambda: "", [], trigger_input)
371
 
372
  results_clear = gr.Button("Clear Results")
373
  results_clear.click(
374
- lambda: ["", "", None],
375
  [],
376
- [trigger_output, trigger_validation_output, trigger_chart]
377
  )
378
 
379
  with gr.Tab("CloudCraze Object Conversion"):
@@ -385,18 +505,35 @@ def main():
385
  placeholder="Paste CC object code here...",
386
  label="CloudCraze Object Code"
387
  )
388
- object_output = gr.Textbox(
389
- lines=15,
390
- label="Converted B2B LEx Object",
391
- interactive=True
392
- )
393
- object_button = gr.Button("Convert Object")
394
- object_button.click(
395
- fn=convert_cc_object,
396
- inputs=[primary_model_dropdown, object_input],
397
- outputs=object_output,
398
- show_progress=True
399
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
 
401
  gr.Markdown("### Validation Results")
402
  with gr.Row():
@@ -418,24 +555,66 @@ def main():
418
  chart = create_radar_chart(metrics) if metrics else None
419
  return validation_text, chart
420
 
 
 
 
 
 
 
 
 
421
  validate_object_button.click(
422
  fn=validate_and_chart_object,
423
- inputs=[validation_model_dropdown, object_input, object_output],
424
  outputs=[object_validation_output, object_chart],
425
  show_progress=True
426
  )
427
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
  with gr.Row():
429
  object_clear = gr.Button("Clear Input")
430
  object_clear.click(lambda: "", [], object_input)
431
 
432
  object_results_clear = gr.Button("Clear Results")
433
  object_results_clear.click(
434
- lambda: ["", "", None],
435
  [],
436
- [object_output, object_validation_output, object_chart]
437
  )
438
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  gr.Markdown("### About This Tool")
440
  gr.Markdown(
441
  """
@@ -445,7 +624,14 @@ def main():
445
  **Object Conversion**: Maps and converts CloudCraze object definitions to B2B LEx.
446
  **Model Selection**: Choose from Together AI models or Anthropic's Claude models.
447
 
448
- **Validation** now outputs four key metrics (quality, accuracy, completeness, best practices) as both JSON and a fun chart.
 
 
 
 
 
 
 
449
  Always review AI-generated code before production use.
450
  """
451
  )
 
5
  import json
6
  import plotly.express as px
7
  import pandas as pd
8
+ import re
9
 
10
  # Model options for dropdown with both Together AI and Anthropic models
11
  together_models = [
 
134
  else:
135
  return f"Error: Unknown provider for model {model}"
136
 
137
+ def extract_code_blocks(text):
138
+ """Extract code blocks from the model's response"""
139
+ # Pattern to match code blocks with ```apex or ```java or just ```
140
+ pattern = r"```(?:apex|java)?(.*?)```"
141
+ matches = re.findall(pattern, text, re.DOTALL)
142
+
143
+ # Clean up extracted code blocks
144
+ code_blocks = []
145
+ for block in matches:
146
+ # Remove leading/trailing whitespace
147
+ cleaned_block = block.strip()
148
+ if cleaned_block:
149
+ code_blocks.append(cleaned_block)
150
+
151
+ # If no code blocks found but text contains code-like content
152
+ if not code_blocks and ("public" in text or "private" in text or "trigger" in text):
153
+ # Try to extract the most code-like part
154
+ lines = text.split('\n')
155
+ potential_code = []
156
+ in_code_section = False
157
+
158
+ for line in lines:
159
+ if any(keyword in line for keyword in ["public", "private", "class", "trigger", "@"]):
160
+ in_code_section = True
161
+
162
+ if in_code_section:
163
+ potential_code.append(line)
164
+
165
+ if potential_code:
166
+ code_blocks.append('\n'.join(potential_code))
167
+
168
+ return '\n\n'.join(code_blocks) if code_blocks else ""
169
+
170
+ def extract_explanations(text, code_blocks):
171
+ """Extract explanations from the model's response by removing code blocks"""
172
+ # Replace all code blocks with placeholders
173
+ explanation = text
174
+ for block in code_blocks.split('\n\n'):
175
+ # Escape special regex characters in the block
176
+ escaped_block = re.escape(block)
177
+ explanation = re.sub(escaped_block, "[CODE BLOCK REMOVED]", explanation, flags=re.DOTALL)
178
+
179
+ # Remove code block markers
180
+ explanation = re.sub(r"```(?:apex|java)?.*?```", "", explanation, flags=re.DOTALL)
181
+
182
+ # Clean up the explanation
183
+ explanation = explanation.replace("[CODE BLOCK REMOVED]", "*Code has been moved to the Code Output section*")
184
+
185
+ return explanation.strip()
186
+
187
  def correct_apex_trigger(model, trigger_code):
188
  if not trigger_code.strip():
189
+ return "Please provide Apex Trigger code to correct.", "", ""
190
  prompt = f"""
191
  Please analyze and correct the following Apex Trigger code for migration from CloudCraze to B2B Lightning Experience.
192
  Identify any issues, optimize it according to best practices, and provide the corrected code.
 
195
  {trigger_code}
196
  ```
197
 
198
+ Please return the corrected code with explanations of changes. Put the corrected code in ```apex code blocks.
199
  """
200
+ response = call_llm(model, prompt)
201
+
202
+ # Extract code blocks and explanations
203
+ code_output = extract_code_blocks(response)
204
+ explanation = extract_explanations(response, code_output)
205
+
206
+ return response, code_output, explanation
207
 
208
  def convert_cc_object(model, cc_object_code):
209
  if not cc_object_code.strip():
210
+ return "Please provide CloudCraze Object code to convert.", "", ""
211
  prompt = f"""
212
  Please convert the following CloudCraze Object code to B2B Lightning Experience format.
213
  Identify the corresponding B2B LEx system object, map fields, and provide the full definition.
 
219
  Return:
220
  1. Equivalent B2B LEx object name
221
  2. Field mappings
222
+ 3. Full implementation code in ```apex code blocks
223
  4. Additional steps if needed
224
  """
225
+ response = call_llm(model, prompt)
226
+
227
+ # Extract code blocks and explanations
228
+ code_output = extract_code_blocks(response)
229
+ explanation = extract_explanations(response, code_output)
230
+
231
+ return response, code_output, explanation
232
 
233
  def validate_apex_trigger(validation_model, original_code, corrected_code):
234
  if not validation_model or not original_code.strip() or not corrected_code.strip():
 
355
 
356
  return fig
357
 
358
+ def toggle_dark_mode(dark_mode, elements):
359
+ """Toggle between light and dark mode for interface elements"""
360
+ if dark_mode:
361
+ style = "background-color: #2e2e2e; color: #ffffff;"
362
+ code_style = "background-color: #1e1e1e; color: #e0e0e0; font-family: 'Courier New', monospace;"
363
+ else:
364
+ style = "background-color: #ffffff; color: #333333;"
365
+ code_style = "background-color: #f5f5f5; color: #333333; font-family: 'Courier New', monospace;"
366
+
367
+ return [style for _ in range(len(elements) // 2)] + [code_style for _ in range(len(elements) // 2)]
368
+
369
  def main():
370
+ with gr.Blocks(title="Salesforce B2B Commerce Migration Assistant", theme=gr.themes.Soft(primary_hue="blue")) as app:
371
+ # Initialize dark mode state
372
+ dark_mode = gr.State(False)
373
+
374
  gr.Markdown("# Salesforce B2B Commerce Migration Assistant")
375
  gr.Markdown("This tool helps migrate CloudCraze code to B2B Lightning Experience.")
376
 
 
402
  placeholder="Paste Apex Trigger code here...",
403
  label="Apex Trigger Code"
404
  )
405
+
406
+ with gr.Row():
407
+ trigger_button = gr.Button("Correct Apex Trigger", variant="primary")
408
+ copy_code_button = gr.Button("Copy Code", variant="secondary")
409
+
410
+ with gr.Accordion("Full Model Response (Hidden by Default)", open=False):
411
+ trigger_full_response = gr.Textbox(
412
+ lines=15,
413
+ label="Full Model Response",
414
+ interactive=False
415
+ )
416
+
417
+ with gr.Row():
418
+ with gr.Column():
419
+ trigger_explanation = gr.Textbox(
420
+ lines=10,
421
+ label="Explanation",
422
+ placeholder="Explanation will appear here after correction",
423
+ interactive=False,
424
+ elem_id="trigger_explanation"
425
+ )
426
+
427
+ with gr.Column():
428
+ trigger_code_output = gr.Code(
429
+ language="java",
430
+ label="Corrected Code",
431
+ value="// Corrected code will appear here",
432
+ elem_id="trigger_code_output"
433
+ )
434
 
435
  gr.Markdown("### Validation Results")
436
  with gr.Row():
 
452
  chart = create_radar_chart(metrics) if metrics else None
453
  return validation_text, chart
454
 
455
+ # Handle button clicks
456
+ trigger_button.click(
457
+ fn=correct_apex_trigger,
458
+ inputs=[primary_model_dropdown, trigger_input],
459
+ outputs=[trigger_full_response, trigger_code_output, trigger_explanation],
460
+ show_progress=True
461
+ )
462
+
463
  validate_trigger_button.click(
464
  fn=validate_and_chart_trigger,
465
+ inputs=[validation_model_dropdown, trigger_input, trigger_code_output],
466
  outputs=[trigger_validation_output, trigger_chart],
467
  show_progress=True
468
  )
469
 
470
+ # Copy code button functionality
471
+ def trigger_copy_to_clipboard():
472
+ # This function doesn't need to return anything - the copy happens in the frontend
473
+ return None
474
+
475
+ copy_code_button.click(
476
+ fn=trigger_copy_to_clipboard,
477
+ inputs=[],
478
+ outputs=[],
479
+ _js="""() => {
480
+ const codeElem = document.getElementById('trigger_code_output');
481
+ if (codeElem) {
482
+ navigator.clipboard.writeText(codeElem.textContent);
483
+ return [];
484
+ }
485
+ }"""
486
+ )
487
+
488
  with gr.Row():
489
  trigger_clear = gr.Button("Clear Input")
490
  trigger_clear.click(lambda: "", [], trigger_input)
491
 
492
  results_clear = gr.Button("Clear Results")
493
  results_clear.click(
494
+ lambda: ["", "", "", "", None],
495
  [],
496
+ [trigger_full_response, trigger_code_output, trigger_explanation, trigger_validation_output, trigger_chart]
497
  )
498
 
499
  with gr.Tab("CloudCraze Object Conversion"):
 
505
  placeholder="Paste CC object code here...",
506
  label="CloudCraze Object Code"
507
  )
508
+
509
+ with gr.Row():
510
+ object_button = gr.Button("Convert Object", variant="primary")
511
+ object_copy_code_button = gr.Button("Copy Code", variant="secondary")
512
+
513
+ with gr.Accordion("Full Model Response (Hidden by Default)", open=False):
514
+ object_full_response = gr.Textbox(
515
+ lines=15,
516
+ label="Full Model Response",
517
+ interactive=False
518
+ )
519
+
520
+ with gr.Row():
521
+ with gr.Column():
522
+ object_explanation = gr.Textbox(
523
+ lines=10,
524
+ label="Explanation",
525
+ placeholder="Explanation will appear here after conversion",
526
+ interactive=False,
527
+ elem_id="object_explanation"
528
+ )
529
+
530
+ with gr.Column():
531
+ object_code_output = gr.Code(
532
+ language="java",
533
+ label="Converted Code",
534
+ value="// Converted code will appear here",
535
+ elem_id="object_code_output"
536
+ )
537
 
538
  gr.Markdown("### Validation Results")
539
  with gr.Row():
 
555
  chart = create_radar_chart(metrics) if metrics else None
556
  return validation_text, chart
557
 
558
+ # Handle button clicks
559
+ object_button.click(
560
+ fn=convert_cc_object,
561
+ inputs=[primary_model_dropdown, object_input],
562
+ outputs=[object_full_response, object_code_output, object_explanation],
563
+ show_progress=True
564
+ )
565
+
566
  validate_object_button.click(
567
  fn=validate_and_chart_object,
568
+ inputs=[validation_model_dropdown, object_input, object_code_output],
569
  outputs=[object_validation_output, object_chart],
570
  show_progress=True
571
  )
572
 
573
+ # Copy code button functionality
574
+ def object_copy_to_clipboard():
575
+ # This function doesn't need to return anything - the copy happens in the frontend
576
+ return None
577
+
578
+ object_copy_code_button.click(
579
+ fn=object_copy_to_clipboard,
580
+ inputs=[],
581
+ outputs=[],
582
+ _js="""() => {
583
+ const codeElem = document.getElementById('object_code_output');
584
+ if (codeElem) {
585
+ navigator.clipboard.writeText(codeElem.textContent);
586
+ return [];
587
+ }
588
+ }"""
589
+ )
590
+
591
  with gr.Row():
592
  object_clear = gr.Button("Clear Input")
593
  object_clear.click(lambda: "", [], object_input)
594
 
595
  object_results_clear = gr.Button("Clear Results")
596
  object_results_clear.click(
597
+ lambda: ["", "", "", "", None],
598
  [],
599
+ [object_full_response, object_code_output, object_explanation, object_validation_output, object_chart]
600
  )
601
 
602
+ # UI Preferences
603
+ with gr.Accordion("UI Preferences", open=False):
604
+ dark_mode_toggle = gr.Checkbox(label="Dark Mode", value=False)
605
+
606
+ # Create a list of UI elements to update
607
+ ui_elements = [
608
+ trigger_explanation, trigger_code_output,
609
+ object_explanation, object_code_output
610
+ ]
611
+
612
+ dark_mode_toggle.change(
613
+ fn=toggle_dark_mode,
614
+ inputs=[dark_mode_toggle, gr.State(ui_elements)],
615
+ outputs=ui_elements
616
+ )
617
+
618
  gr.Markdown("### About This Tool")
619
  gr.Markdown(
620
  """
 
624
  **Object Conversion**: Maps and converts CloudCraze object definitions to B2B LEx.
625
  **Model Selection**: Choose from Together AI models or Anthropic's Claude models.
626
 
627
+ **New Interface Features**:
628
+ - Separated code output in dedicated code editor interface with syntax highlighting
629
+ - Clear separation between explanations and code
630
+ - "Copy Code" button for easy copying
631
+ - Dark mode option for comfortable viewing
632
+ - Hidden full model response to reduce clutter
633
+
634
+ **Validation** outputs four key metrics (quality, accuracy, completeness, best practices) as both JSON and a radar chart.
635
  Always review AI-generated code before production use.
636
  """
637
  )