Update app.py
Browse files
app.py
CHANGED
|
@@ -545,22 +545,16 @@ def get_recommendation_with_agent(user_id, merchant, category, amount):
|
|
| 545 |
- 60-69: Acceptable β οΈ
|
| 546 |
- <60: Suboptimal β
|
| 547 |
"""
|
| 548 |
-
|
| 549 |
def format_reasoning(text):
|
| 550 |
"""Format reasoning text into clean bullet points"""
|
| 551 |
-
# If already has bullet points or numbered lists, use as-is
|
| 552 |
if text.strip().startswith(('-', 'β’', '*', '1.', '2.')):
|
| 553 |
return text
|
| 554 |
|
| 555 |
-
# Split into sentences
|
| 556 |
sentences = text.replace('\n', ' ').split('. ')
|
| 557 |
-
|
| 558 |
-
# Take first 3-4 meaningful sentences
|
| 559 |
bullets = []
|
| 560 |
for sentence in sentences[:4]:
|
| 561 |
sentence = sentence.strip()
|
| 562 |
-
if sentence and len(sentence) > 20:
|
| 563 |
-
# Add period if missing
|
| 564 |
if not sentence.endswith('.'):
|
| 565 |
sentence += '.'
|
| 566 |
bullets.append(f"- {sentence}")
|
|
@@ -569,25 +563,26 @@ def get_recommendation_with_agent(user_id, merchant, category, amount):
|
|
| 569 |
|
| 570 |
reasoning_bullets = format_reasoning(reasoning)
|
| 571 |
|
|
|
|
| 572 |
output = f"""## π― Recommended: **{card_name}**
|
| 573 |
-
|
| 574 |
-
| Metric | Value |
|
| 575 |
-
|--------|-------|
|
| 576 |
-
| π° **Rewards Earned** | ${rewards_earned:.2f} ({rewards_rate}) |
|
| 577 |
-
| π **Confidence** | {confidence*100:.0f}% |
|
| 578 |
-
| π **Annual Potential** | ${net_benefit:.2f}/year |
|
| 579 |
-
| β **Optimization Score** | {optimization_score}/100 |
|
| 580 |
-
|
| 581 |
-
---
|
| 582 |
-
|
| 583 |
-
### π§ Why This Card?
|
| 584 |
-
|
| 585 |
-
{reasoning_bullets}
|
| 586 |
-
|
| 587 |
-
---
|
| 588 |
-
"""
|
| 589 |
|
| 590 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 591 |
if alternatives:
|
| 592 |
output += "\n### π Alternative Options\n\n"
|
| 593 |
output += "| Card | Rewards | Why? |\n"
|
|
@@ -597,16 +592,22 @@ def get_recommendation_with_agent(user_id, merchant, category, amount):
|
|
| 597 |
alt_card_name = card_name_map.get(alt_card_id, alt_card_id.replace('c_', '').replace('_', ' ').title())
|
| 598 |
alt_reason = alt.get('reason', 'Good alternative')
|
| 599 |
alt_reward = alt.get('reward_amount', rewards_earned * 0.8)
|
| 600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 601 |
output += f"| {alt_card_name} | ${alt_reward:.2f} | {alt_reason_short} |\n"
|
| 602 |
output += "\n---\n"
|
| 603 |
|
|
|
|
| 604 |
if warnings:
|
| 605 |
output += "\n### β οΈ Alerts\n\n"
|
| 606 |
for warning in warnings:
|
| 607 |
output += f"- {warning}\n"
|
| 608 |
output += "\n---\n"
|
| 609 |
|
|
|
|
| 610 |
output += f"""
|
| 611 |
<details>
|
| 612 |
<summary>π <b>Annual Impact Calculation</b> (Click to expand)</summary>
|
|
|
|
| 545 |
- 60-69: Acceptable β οΈ
|
| 546 |
- <60: Suboptimal β
|
| 547 |
"""
|
|
|
|
| 548 |
def format_reasoning(text):
|
| 549 |
"""Format reasoning text into clean bullet points"""
|
|
|
|
| 550 |
if text.strip().startswith(('-', 'β’', '*', '1.', '2.')):
|
| 551 |
return text
|
| 552 |
|
|
|
|
| 553 |
sentences = text.replace('\n', ' ').split('. ')
|
|
|
|
|
|
|
| 554 |
bullets = []
|
| 555 |
for sentence in sentences[:4]:
|
| 556 |
sentence = sentence.strip()
|
| 557 |
+
if sentence and len(sentence) > 20:
|
|
|
|
| 558 |
if not sentence.endswith('.'):
|
| 559 |
sentence += '.'
|
| 560 |
bullets.append(f"- {sentence}")
|
|
|
|
| 563 |
|
| 564 |
reasoning_bullets = format_reasoning(reasoning)
|
| 565 |
|
| 566 |
+
# Gradio-friendly markdown output
|
| 567 |
output = f"""## π― Recommended: **{card_name}**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 568 |
|
| 569 |
+
| Metric | Value |
|
| 570 |
+
|--------|-------|
|
| 571 |
+
| π° **Rewards Earned** | ${rewards_earned:.2f} ({rewards_rate}) |
|
| 572 |
+
| π **Confidence** | {confidence*100:.0f}% |
|
| 573 |
+
| π **Annual Potential** | ${net_benefit:.2f}/year |
|
| 574 |
+
| β **Optimization Score** | {optimization_score}/100 |
|
| 575 |
+
|
| 576 |
+
---
|
| 577 |
+
|
| 578 |
+
### π§ Why This Card?
|
| 579 |
+
|
| 580 |
+
{reasoning_bullets}
|
| 581 |
+
|
| 582 |
+
---
|
| 583 |
+
"""
|
| 584 |
+
|
| 585 |
+
# Alternatives
|
| 586 |
if alternatives:
|
| 587 |
output += "\n### π Alternative Options\n\n"
|
| 588 |
output += "| Card | Rewards | Why? |\n"
|
|
|
|
| 592 |
alt_card_name = card_name_map.get(alt_card_id, alt_card_id.replace('c_', '').replace('_', ' ').title())
|
| 593 |
alt_reason = alt.get('reason', 'Good alternative')
|
| 594 |
alt_reward = alt.get('reward_amount', rewards_earned * 0.8)
|
| 595 |
+
|
| 596 |
+
alt_reason_short = alt_reason.split('.')[0].strip()
|
| 597 |
+
if not alt_reason_short.endswith('.'):
|
| 598 |
+
alt_reason_short += '.'
|
| 599 |
+
|
| 600 |
output += f"| {alt_card_name} | ${alt_reward:.2f} | {alt_reason_short} |\n"
|
| 601 |
output += "\n---\n"
|
| 602 |
|
| 603 |
+
# Warnings
|
| 604 |
if warnings:
|
| 605 |
output += "\n### β οΈ Alerts\n\n"
|
| 606 |
for warning in warnings:
|
| 607 |
output += f"- {warning}\n"
|
| 608 |
output += "\n---\n"
|
| 609 |
|
| 610 |
+
|
| 611 |
output += f"""
|
| 612 |
<details>
|
| 613 |
<summary>π <b>Annual Impact Calculation</b> (Click to expand)</summary>
|