ankitxraj21 commited on
Commit
15e0c2f
ยท
verified ยท
1 Parent(s): ae44b00

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +269 -79
app.py CHANGED
@@ -1,128 +1,318 @@
1
  import gradio as gr
2
  import random
3
- import time
4
- import os
 
 
 
5
  from datetime import datetime
6
- from environment import CloudCostEnv
7
- from inference import get_action_from_llama
8
 
9
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
10
- # Import your friend's code here (Step 3)
11
- # from cloud_guardian import run_agent
12
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
 
 
 
 
 
 
 
 
 
13
 
14
- def get_timestamp():
15
- return datetime.now().strftime("%H:%M:%S")
 
 
 
 
 
 
 
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  def run_simulation(scenario, user_load, spot_avail, chaos_monkey, budget_on, auto_scaling):
18
- """
19
- RIGHT NOW: uses fake random data so you can see the UI work.
20
- LATER: replace the inside with your friend's real function.
21
- """
22
- t = get_timestamp()
23
-
24
- # Fake metrics โ€” replace with real ones later
25
- load = int(user_load * 10)
26
- servers = random.randint(8, 20)
27
- burn_rate = round(random.uniform(0.2, 0.6), 2)
28
- latency = random.randint(30, 120)
29
- score = round(random.uniform(0.75, 1.0), 2)
30
-
31
- spend = "$680" if auto_scaling else "$1,250"
32
- downtime = "๐ŸŸข Low" if auto_scaling else "๐ŸŸก Medium"
33
-
34
- log = f"[{t}] Load: {load} โ†’ ACTION: Add Instance (t3.medium)\n"
35
- log += f"[{t}] Latency improved to {latency}ms. Budget Remaining: $12\n"
36
- log += f"[{t}] Cost > Threshold โ†’ ACTION: Switch to Spot Instance\n"
37
- log += f"[{t}] Final Score: {score} / 1.0"
 
 
 
38
 
39
  return (
40
- f"๐Ÿ”ฅ {load} req/sec",
41
- f"๐Ÿ–ฅ๏ธ {servers} instances",
42
- f"๐Ÿ’ธ ${burn_rate}/hr",
 
43
  log,
44
  spend,
45
  downtime,
46
- score
 
 
 
 
 
 
47
  )
48
 
49
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  # BUILD THE UI
51
- # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
52
- with gr.Blocks(
53
- title="โ˜๏ธ Cloud-Cost Guardian AI",
54
- theme=gr.themes.Base(
55
- primary_hue="cyan",
56
- neutral_hue="slate",
57
- ),
58
- css="""
59
- .gradio-container { max-width: 1100px !important; }
60
- .metric-box { text-align: center; font-size: 1.4em; font-weight: bold; }
61
- """
62
- ) as demo:
63
-
64
- # โ”€โ”€ Header โ”€โ”€
65
  gr.Markdown("""
66
  # โ˜๏ธ Cloud-Cost Guardian AI
67
- ### Live Simulation Dashboard
68
  ---
69
  """)
70
 
71
- # โ”€โ”€ Metric cards row โ”€โ”€
72
  with gr.Row():
73
- load_out = gr.Textbox(label="๐Ÿ“ˆ Incoming Load", elem_classes="metric-box", interactive=False)
74
- server_out = gr.Textbox(label="๐Ÿ–ฅ๏ธ Active Servers", elem_classes="metric-box", interactive=False)
75
- burn_out = gr.Textbox(label="๐Ÿ’ธ Hourly Burn Rate", elem_classes="metric-box", interactive=False)
 
76
 
77
  gr.Markdown("---")
78
 
79
- # โ”€โ”€ Controls + Log side by side โ”€โ”€
80
  with gr.Row():
81
-
82
- # Left column โ€” controls
83
  with gr.Column(scale=1):
84
  gr.Markdown("### ๐ŸŽฎ Simulation Controls")
85
-
86
  scenario = gr.Dropdown(
87
  choices=[
88
  "Scenario 1: Steady Load (Easy)",
89
  "Scenario 2: Daily Peak Surges (Medium)",
90
- "Scenario 3: Chaos Mode (Hard)"
91
  ],
92
  value="Scenario 2: Daily Peak Surges (Medium)",
93
- label="Select Scenario"
94
  )
95
  user_load = gr.Slider(0, 100, value=75, step=1, label="User Load Scale (%)")
96
  spot_avail = gr.Slider(0, 100, value=40, step=1, label="Spot Instance Availability (%)")
97
- chaos_monkey = gr.Checkbox(value=False, label="๐Ÿ’ Chaos Monkey (Hard Tasks)")
98
  budget_constr= gr.Checkbox(value=True, label="๐Ÿ’ฐ Budget Constraint")
99
- auto_scaling = gr.Checkbox(value=True, label="๐Ÿค– Auto-Scaling Agent")
100
-
101
- run_btn = gr.Button("๐Ÿš€ Reset Environment & Restart Agent", variant="primary", size="lg")
102
 
103
- # Right column โ€” outputs
104
  with gr.Column(scale=2):
105
  gr.Markdown("### ๐Ÿ“‹ Agent Action Log")
106
- log_out = gr.Textbox(lines=6, label="Live Log", interactive=False)
107
-
108
  with gr.Row():
109
- spend_out = gr.Textbox(label="Total Spend", interactive=False)
110
- risk_out = gr.Textbox(label="Downtime Risk", interactive=False)
111
-
112
  score_out = gr.Number(label="๐Ÿ† Final Agent Score (out of 1.0)", interactive=False)
113
 
114
- # โ”€โ”€ Wire button to function โ”€โ”€
115
- run_btn.click(
116
- fn=run_simulation,
117
- inputs=[scenario, user_load, spot_avail, chaos_monkey, budget_constr, auto_scaling],
118
- outputs=[load_out, server_out, burn_out, log_out, spend_out, risk_out, score_out]
119
- )
 
 
 
 
 
 
 
120
 
121
  gr.Markdown("""
122
  ---
123
- > ๐Ÿ’ก Tip: Click **Reset Environment** after changing any setting to see updated results.
124
  """)
125
 
126
- # โ”€โ”€ Launch โ”€โ”€
 
 
 
 
 
 
 
 
 
 
127
  if __name__ == "__main__":
128
- demo.launch(share=True) # share=True gives you a public link
 
1
  import gradio as gr
2
  import random
3
+ import matplotlib
4
+ matplotlib.use('Agg')
5
+ import matplotlib.pyplot as plt
6
+ import matplotlib.patches as mpatches
7
+ import numpy as np
8
  from datetime import datetime
 
 
9
 
10
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
11
+ # DARK THEME STYLE FOR ALL CHARTS
12
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
13
+ DARK = {
14
+ "bg": "#0a0e1a",
15
+ "panel": "#111827",
16
+ "cyan": "#00e5ff",
17
+ "green": "#00ff9d",
18
+ "amber": "#ffb300",
19
+ "red": "#ff4d6d",
20
+ "muted": "#64748b",
21
+ "text": "#e2e8f0",
22
+ }
23
 
24
+ def style_ax(ax, fig):
25
+ fig.patch.set_facecolor(DARK["panel"])
26
+ ax.set_facecolor(DARK["panel"])
27
+ ax.tick_params(colors=DARK["muted"], labelsize=8)
28
+ ax.xaxis.label.set_color(DARK["muted"])
29
+ ax.yaxis.label.set_color(DARK["muted"])
30
+ for spine in ax.spines.values():
31
+ spine.set_edgecolor("#1e2d45")
32
+ ax.grid(True, color="#1e2d45", linewidth=0.5, linestyle="--", alpha=0.6)
33
 
34
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
35
+ # CHART 1 โ€” Traffic & Server Scaling (Line)
36
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
37
+ def make_traffic_chart(user_load):
38
+ steps = 90
39
+ t = np.arange(steps)
40
+ base_load = user_load * 8
41
+ load = base_load + 200 * np.sin(t / 12) + np.random.normal(0, 30, steps)
42
+ load = np.clip(load, 0, 1000)
43
+ servers = load / 70 + np.random.normal(0, 0.5, steps)
44
+ servers = np.clip(servers, 1, 20)
45
+
46
+ fig, ax = plt.subplots(figsize=(5, 2.6))
47
+ style_ax(ax, fig)
48
+ ax.plot(t, load, color=DARK["green"], linewidth=1.5, label="Incoming load")
49
+ ax.plot(t, servers * 40, color=DARK["cyan"], linewidth=1.5, label="Active servers (ร—40)", linestyle="--")
50
+ ax.set_xlabel("Time (steps)", fontsize=8)
51
+ ax.set_ylabel("Load", fontsize=8)
52
+ ax.set_title("Traffic & Server Scaling", color=DARK["text"], fontsize=10, pad=8)
53
+ p1 = mpatches.Patch(color=DARK["green"], label="Incoming load")
54
+ p2 = mpatches.Patch(color=DARK["cyan"], label="Active servers")
55
+ ax.legend(handles=[p1, p2], fontsize=7, facecolor=DARK["panel"],
56
+ labelcolor=DARK["text"], edgecolor="#1e2d45", loc="upper right")
57
+ plt.tight_layout(pad=0.8)
58
+ return fig
59
+
60
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
61
+ # CHART 2 โ€” Cost Efficiency (Line + target budget line)
62
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
63
+ def make_cost_chart(budget_on, spot_avail):
64
+ steps = 90
65
+ t = np.arange(steps)
66
+ budget_line = 0.50
67
+ burn = 0.80 * np.exp(-t / 40) + 0.05 + np.random.normal(0, 0.02, steps)
68
+ if budget_on:
69
+ burn = np.clip(burn, None, budget_line + 0.05)
70
+ if spot_avail > 50:
71
+ burn *= 0.75
72
+
73
+ fig, ax = plt.subplots(figsize=(5, 2.6))
74
+ style_ax(ax, fig)
75
+ ax.plot(t, burn, color=DARK["red"], linewidth=1.5, label="Hourly burn rate ($)")
76
+ ax.axhline(budget_line, color=DARK["amber"], linewidth=1, linestyle="--", label="Target budget")
77
+ ax.set_xlabel("Time (steps)", fontsize=8)
78
+ ax.set_ylabel("Hourly burn rate ($)", fontsize=8)
79
+ ax.set_title("Cost Efficiency", color=DARK["text"], fontsize=10, pad=8)
80
+ p1 = mpatches.Patch(color=DARK["red"], label="Hourly burn rate ($)")
81
+ p2 = mpatches.Patch(color=DARK["amber"], label="Target budget")
82
+ ax.legend(handles=[p1, p2], fontsize=7, facecolor=DARK["panel"],
83
+ labelcolor=DARK["text"], edgecolor="#1e2d45")
84
+ plt.tight_layout(pad=0.8)
85
+ return fig
86
+
87
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
88
+ # CHART 3 โ€” Response Performance (Line)
89
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
90
+ def make_perf_chart(chaos_monkey):
91
+ steps = 90
92
+ t = np.arange(steps)
93
+ latency = 40 + 20 * np.sin(t / 15) + np.random.normal(0, 5, steps)
94
+ if chaos_monkey:
95
+ spikes = np.random.choice(steps, size=6, replace=False)
96
+ latency[spikes] += np.random.uniform(80, 160, size=6)
97
+ latency = np.clip(latency, 0, 200)
98
+
99
+ fig, ax = plt.subplots(figsize=(5, 2.6))
100
+ style_ax(ax, fig)
101
+ ax.plot(t, latency, color=DARK["amber"], linewidth=1.5)
102
+ ax.fill_between(t, latency, alpha=0.15, color=DARK["amber"])
103
+ ax.set_xlabel("Time (steps)", fontsize=8)
104
+ ax.set_ylabel("Avg latency (ms)", fontsize=8)
105
+ ax.set_title("Response Performance (99th pct SLA)", color=DARK["text"], fontsize=10, pad=8)
106
+ plt.tight_layout(pad=0.8)
107
+ return fig
108
+
109
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
110
+ # CHART 4 โ€” Cumulative Reward (Area)
111
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
112
+ def make_reward_chart(auto_scaling):
113
+ episodes = np.arange(1, 201)
114
+ if auto_scaling:
115
+ reward = 1000 * (1 - np.exp(-episodes / 60)) + np.random.normal(0, 20, 200)
116
+ else:
117
+ reward = 400 * (1 - np.exp(-episodes / 80)) + np.random.normal(0, 15, 200)
118
+ reward = np.cumsum(np.clip(reward / 200, 0, None))
119
+
120
+ fig, ax = plt.subplots(figsize=(5, 2.6))
121
+ style_ax(ax, fig)
122
+ color = DARK["cyan"] if auto_scaling else DARK["muted"]
123
+ ax.plot(episodes, reward, color=color, linewidth=1.5)
124
+ ax.fill_between(episodes, reward, alpha=0.15, color=color)
125
+ ax.set_xlabel("Episodes", fontsize=8)
126
+ ax.set_ylabel("Cumulative reward", fontsize=8)
127
+ ax.set_title("Cumulative Reward over Episodes", color=DARK["text"], fontsize=10, pad=8)
128
+ plt.tight_layout(pad=0.8)
129
+ return fig
130
+
131
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
132
+ # CHART 5 โ€” Cost Comparison Bar (Before vs After RL)
133
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
134
+ def make_comparison_chart(auto_scaling):
135
+ labels = ["Static\n(Before)", "RL Agent\n(After)"]
136
+ spend = [1250, 680 if auto_scaling else 1050]
137
+ downtime = [35, 8 if auto_scaling else 22]
138
+
139
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(5, 2.6))
140
+ for ax in (ax1, ax2):
141
+ style_ax(ax, fig)
142
+
143
+ colors = [DARK["muted"], DARK["green"] if auto_scaling else DARK["amber"]]
144
+ ax1.bar(labels, spend, color=colors, width=0.5, edgecolor="#1e2d45")
145
+ ax1.set_title("Total spend ($)", color=DARK["text"], fontsize=9)
146
+ ax1.set_ylabel("$", fontsize=8)
147
+ for i, v in enumerate(spend):
148
+ ax1.text(i, v + 20, f"${v}", ha="center", color=DARK["text"], fontsize=8)
149
+
150
+ ax2.bar(labels, downtime, color=colors, width=0.5, edgecolor="#1e2d45")
151
+ ax2.set_title("Downtime risk (%)", color=DARK["text"], fontsize=9)
152
+ ax2.set_ylabel("%", fontsize=8)
153
+ for i, v in enumerate(downtime):
154
+ ax2.text(i, v + 0.5, f"{v}%", ha="center", color=DARK["text"], fontsize=8)
155
+
156
+ plt.suptitle("Before vs After RL", color=DARK["text"], fontsize=10, y=1.02)
157
+ plt.tight_layout(pad=0.8)
158
+ return fig
159
+
160
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
161
+ # MAIN SIMULATION FUNCTION
162
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
163
  def run_simulation(scenario, user_load, spot_avail, chaos_monkey, budget_on, auto_scaling):
164
+ t = datetime.now().strftime("%H:%M:%S")
165
+
166
+ load = int(user_load * 10)
167
+ servers = random.randint(8, 20)
168
+ burn = round(random.uniform(0.2, 0.5 if budget_on else 0.8), 2)
169
+ latency = random.randint(25, 80 if not chaos_monkey else 160)
170
+ score = round(random.uniform(0.80, 1.0) if auto_scaling else random.uniform(0.55, 0.80), 2)
171
+ spend = "$680" if auto_scaling else "$1,250"
172
+ downtime = "Low" if auto_scaling else "Medium"
173
+ savings = "45%" if auto_scaling else "0%"
174
+
175
+ log = f"[{t}] Scenario : {scenario}\n"
176
+ log += f"[{t}] Load : {load} req/s โ†’ Servers: {servers}\n"
177
+ log += f"[{t}] Latency : {latency} ms\n"
178
+ log += f"[{t}] Burn rate : ${burn}/hr\n"
179
+ log += f"[{t}] ACTION : {'Scale up (RL agent)' if auto_scaling else 'Static allocation'}\n"
180
+ log += f"[{t}] Score : {score} / 1.0"
181
+
182
+ traffic_fig = make_traffic_chart(user_load)
183
+ cost_fig = make_cost_chart(budget_on, spot_avail)
184
+ perf_fig = make_perf_chart(chaos_monkey)
185
+ reward_fig = make_reward_chart(auto_scaling)
186
+ comparison_fig = make_comparison_chart(auto_scaling)
187
 
188
  return (
189
+ f"๐Ÿ“ˆ {load} req/s",
190
+ f"๐Ÿ–ฅ๏ธ {servers} instances",
191
+ f"๐Ÿ’ธ ${burn}/hr",
192
+ f"โšก {latency} ms",
193
  log,
194
  spend,
195
  downtime,
196
+ savings,
197
+ score,
198
+ traffic_fig,
199
+ cost_fig,
200
+ perf_fig,
201
+ reward_fig,
202
+ comparison_fig,
203
  )
204
 
205
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
206
+ # CUSTOM CSS
207
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
208
+ CSS = """
209
+ body, .gradio-container {
210
+ background: #0a0e1a !important;
211
+ color: #e2e8f0 !important;
212
+ font-family: 'Space Grotesk', 'Segoe UI', sans-serif !important;
213
+ }
214
+ .gr-button-primary {
215
+ background: transparent !important;
216
+ border: 1px solid #00e5ff !important;
217
+ color: #00e5ff !important;
218
+ letter-spacing: 1px;
219
+ font-weight: 600;
220
+ }
221
+ .gr-button-primary:hover {
222
+ background: rgba(0,229,255,0.1) !important;
223
+ }
224
+ .gr-panel, .gr-box {
225
+ background: #111827 !important;
226
+ border: 0.5px solid #1e2d45 !important;
227
+ border-radius: 10px !important;
228
+ }
229
+ label, .gr-input-label { color: #64748b !important; font-size: 12px !important; }
230
+ input, select, textarea {
231
+ background: #0d1525 !important;
232
+ color: #e2e8f0 !important;
233
+ border: 0.5px solid #1e2d45 !important;
234
+ }
235
+ .gr-plot { background: #111827 !important; border: 0.5px solid #1e2d45 !important; border-radius: 8px !important; }
236
+ """
237
+
238
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
239
  # BUILD THE UI
240
+ # โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
241
+ with gr.Blocks(css=CSS, title="โ˜๏ธ Cloud-Cost Guardian AI") as demo:
242
+
 
 
 
 
 
 
 
 
 
 
 
243
  gr.Markdown("""
244
  # โ˜๏ธ Cloud-Cost Guardian AI
245
+ ### Live Simulation Dashboard โ€” RL-Powered Auto Scaling
246
  ---
247
  """)
248
 
249
+ # โ”€โ”€ Row 1: Metric cards โ”€โ”€
250
  with gr.Row():
251
+ load_out = gr.Textbox(label="Incoming Load", interactive=False)
252
+ server_out = gr.Textbox(label="Active Servers", interactive=False)
253
+ burn_out = gr.Textbox(label="Hourly Burn Rate", interactive=False)
254
+ latency_out = gr.Textbox(label="Avg Latency", interactive=False)
255
 
256
  gr.Markdown("---")
257
 
258
+ # โ”€โ”€ Row 2: Controls + Log โ”€โ”€
259
  with gr.Row():
 
 
260
  with gr.Column(scale=1):
261
  gr.Markdown("### ๐ŸŽฎ Simulation Controls")
 
262
  scenario = gr.Dropdown(
263
  choices=[
264
  "Scenario 1: Steady Load (Easy)",
265
  "Scenario 2: Daily Peak Surges (Medium)",
266
+ "Scenario 3: Chaos Mode (Hard)",
267
  ],
268
  value="Scenario 2: Daily Peak Surges (Medium)",
269
+ label="Scenario"
270
  )
271
  user_load = gr.Slider(0, 100, value=75, step=1, label="User Load Scale (%)")
272
  spot_avail = gr.Slider(0, 100, value=40, step=1, label="Spot Instance Availability (%)")
273
+ chaos_monkey = gr.Checkbox(value=False, label="๐Ÿ’ Chaos Monkey")
274
  budget_constr= gr.Checkbox(value=True, label="๐Ÿ’ฐ Budget Constraint")
275
+ auto_scaling = gr.Checkbox(value=True, label="๐Ÿค– Auto-Scaling Agent (RL)")
276
+ run_btn = gr.Button("๐Ÿš€ Reset & Restart Agent", variant="primary", size="lg")
 
277
 
 
278
  with gr.Column(scale=2):
279
  gr.Markdown("### ๐Ÿ“‹ Agent Action Log")
280
+ log_out = gr.Textbox(lines=7, label="Live Log", interactive=False)
 
281
  with gr.Row():
282
+ spend_out = gr.Textbox(label="Total Spend", interactive=False)
283
+ risk_out = gr.Textbox(label="Downtime Risk", interactive=False)
284
+ savings_out = gr.Textbox(label="Cost Savings", interactive=False)
285
  score_out = gr.Number(label="๐Ÿ† Final Agent Score (out of 1.0)", interactive=False)
286
 
287
+ gr.Markdown("---")
288
+ gr.Markdown("### ๐Ÿ“Š Live Performance Graphs")
289
+
290
+ # โ”€โ”€ Row 3: Top 3 charts โ”€โ”€
291
+ with gr.Row():
292
+ traffic_plot = gr.Plot(label="Traffic & Server Scaling")
293
+ cost_plot = gr.Plot(label="Cost Efficiency")
294
+ perf_plot = gr.Plot(label="Response Performance")
295
+
296
+ # โ”€โ”€ Row 4: Bottom 2 charts โ”€โ”€
297
+ with gr.Row():
298
+ reward_plot = gr.Plot(label="Cumulative Reward (RL Training)")
299
+ comparison_plot = gr.Plot(label="Before vs After RL")
300
 
301
  gr.Markdown("""
302
  ---
303
+ > ๐Ÿ’ก Adjust any control above and click **Reset & Restart Agent** to see all graphs update live.
304
  """)
305
 
306
+ # โ”€โ”€ Wire everything up โ”€โ”€
307
+ run_btn.click(
308
+ fn=run_simulation,
309
+ inputs=[scenario, user_load, spot_avail, chaos_monkey, budget_constr, auto_scaling],
310
+ outputs=[
311
+ load_out, server_out, burn_out, latency_out,
312
+ log_out, spend_out, risk_out, savings_out, score_out,
313
+ traffic_plot, cost_plot, perf_plot, reward_plot, comparison_plot,
314
+ ]
315
+ )
316
+
317
  if __name__ == "__main__":
318
+ demo.launch(share=True)