trading-tools / web /components /budget_alerts.py
Deploy Bot
Deploy Trading Analysis Platform to HuggingFace Spaces
a1bf219
"""Budget configuration and alert UI components."""
from typing import Optional, Tuple
import gradio as gr
def create_budget_configuration() -> Tuple[
gr.Number, gr.Slider, gr.Slider, gr.Checkbox
]:
"""Create budget configuration input components.
Returns:
Tuple of (budget_limit, threshold_75, threshold_90, require_confirmation)
"""
with gr.Accordion("💰 Budget Management", open=False):
gr.Markdown("""
### Budget Configuration
Set cost limits and receive alerts when approaching your budget. This helps prevent unexpected API costs.
**Threshold Alerts:**
- **75%**: Info alert - you're getting close to your budget
- **90%**: Warning alert - you should monitor usage carefully
- **100%**: Limit reached - workflow can be paused for confirmation
""")
budget_limit = gr.Number(
label="Budget Limit (USD)",
value=5.00,
minimum=0.10,
maximum=1000.00,
step=0.10,
info="Maximum cost allowed for this session",
)
threshold_75 = gr.Slider(
label="Info Alert Threshold (%)",
value=75,
minimum=50,
maximum=100,
step=5,
info="Trigger info alert at this percentage of budget",
)
threshold_90 = gr.Slider(
label="Warning Alert Threshold (%)",
value=90,
minimum=75,
maximum=100,
step=5,
info="Trigger warning alert at this percentage of budget",
)
require_confirmation = gr.Checkbox(
label="Require confirmation when budget limit reached",
value=True,
info="Pause workflow at 100% budget and ask for confirmation to continue",
)
return budget_limit, threshold_75, threshold_90, require_confirmation
def create_budget_status_display() -> gr.Textbox:
"""Create budget status display component.
Returns:
Gradio Textbox component for budget status
"""
return gr.Textbox(
label="Budget Status",
value="No budget configured",
interactive=False,
lines=3,
elem_id="budget_status_display",
)
def create_cost_reduction_tips_display() -> gr.Markdown:
"""Create cost reduction tips display component.
Returns:
Gradio Markdown component for tips display
"""
return gr.Markdown(
value="",
visible=False,
elem_id="cost_reduction_tips",
)
def format_budget_status(
enabled: bool,
limit: float = 0,
current_cost: float = 0,
percentage_used: float = 0,
remaining: float = 0,
status: str = "ok",
) -> str:
"""Format budget status message.
Args:
enabled: Whether budget is enabled
limit: Budget limit in USD
current_cost: Current cost in USD
percentage_used: Percentage of budget used
remaining: Remaining budget in USD
status: Status indicator (ok, caution, warning, exceeded)
Returns:
Formatted status string
"""
if not enabled:
return "💤 No budget configured"
status_emoji = {"ok": "✅", "caution": "ℹ️", "warning": "⚠️", "exceeded": "🚨"}
emoji = status_emoji.get(status, "ℹ️")
status_text = f"{emoji} Budget Status: {status.upper()}\n"
status_text += (
f"Used: ${current_cost:.4f} / ${limit:.2f} ({percentage_used:.1f}%)\n"
)
status_text += f"Remaining: ${remaining:.4f}"
return status_text
def format_cost_reduction_tips(tips: list) -> str:
"""Format cost reduction tips as markdown.
Args:
tips: List of tip strings
Returns:
Formatted markdown string
"""
if not tips:
return ""
markdown = "### 💡 Cost Reduction Tips\n\n"
for tip in tips:
markdown += f"- {tip}\n"
return markdown
def create_budget_alert_modal() -> Tuple[gr.Markdown, gr.Button, gr.Button]:
"""Create modal dialog for budget limit confirmation.
Returns:
Tuple of (alert_message, continue_button, cancel_button)
"""
with gr.Column(visible=False, elem_id="budget_alert_modal") as modal:
alert_message = gr.Markdown("Budget limit reached")
with gr.Row():
continue_btn = gr.Button("Continue Anyway", variant="primary")
cancel_btn = gr.Button("Cancel Analysis", variant="stop")
return alert_message, continue_btn, cancel_btn
def show_budget_alert(
threshold: float, current_cost: float, limit: float, tips: list = None
) -> str:
"""Generate budget alert message.
Args:
threshold: Threshold percentage (0.75, 0.90, 1.0)
current_cost: Current cost in USD
limit: Budget limit in USD
tips: Optional cost reduction tips
Returns:
Formatted alert message
"""
percentage = (current_cost / limit) * 100
if threshold == 1.0:
message = f"🚨 **BUDGET LIMIT REACHED**\n\n"
message += f"You've reached your budget limit of ${limit:.2f}\n"
message += f"Current cost: ${current_cost:.4f} ({percentage:.1f}%)"
elif threshold == 0.90:
message = f"⚠️ **Budget Warning (90%)**\n\n"
message += f"You've used {percentage:.1f}% of your ${limit:.2f} budget\n"
message += f"Remaining: ${limit - current_cost:.4f}"
else: # 0.75
message = f"ℹ️ **Budget Notice (75%)**\n\n"
message += f"You've used {percentage:.1f}% of your ${limit:.2f} budget\n"
message += f"Remaining: ${limit - current_cost:.4f}"
if tips:
message += "\n\n### Cost Reduction Tips\n\n"
for tip in tips:
message += f"- {tip}\n"
return message
def apply_budget_configuration(
limit: float, threshold_75: float, threshold_90: float, require_confirmation: bool
) -> Tuple[dict, str]:
"""Apply budget configuration.
Args:
limit: Budget limit in USD
threshold_75: 75% threshold
threshold_90: 90% threshold
require_confirmation: Require confirmation at limit
Returns:
Tuple of (budget_config_dict, status_message)
"""
budget_config = {
"limit": limit,
"threshold_75": threshold_75 / 100.0,
"threshold_90": threshold_90 / 100.0,
"threshold_100": 1.0,
"require_confirmation_at_limit": require_confirmation,
}
status = f"✅ Budget configured: ${limit:.2f} limit\n"
status += f"Alerts at: {threshold_75}%, {threshold_90}%, 100%\n"
status += f"Confirmation required: {'Yes' if require_confirmation else 'No'}"
return budget_config, status
def check_and_display_budget_alert(
cost_tracker, current_provider: str = "huggingface"
) -> Tuple[bool, Optional[str], Optional[list]]:
"""Check budget and generate alert if needed.
Args:
cost_tracker: CostTracker instance
current_provider: Current LLM provider
Returns:
Tuple of (alert_triggered, alert_message, cost_reduction_tips)
"""
if not cost_tracker or not cost_tracker.budget_config:
return False, None, None
threshold_exceeded, message, threshold = cost_tracker.check_budget_threshold()
if threshold_exceeded:
tips = cost_tracker.get_cost_reduction_tips(current_provider)
return True, message, tips
return False, None, None