Spaces:
Sleeping
Sleeping
| """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 | |