Mohammed Thameem commited on
Commit
1f52c8d
ยท
1 Parent(s): 49b0d9a

modified test script

Browse files
Files changed (2) hide show
  1. app.py +129 -69
  2. tests/test_app.py +0 -2
app.py CHANGED
@@ -1,29 +1,83 @@
 
1
  import gradio as gr
2
  from huggingface_hub import InferenceClient
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  def respond(
6
  message,
7
  history: list[dict[str, str]],
8
  system_message,
9
- max_tokens,
10
- temperature,
11
- top_p,
12
- hf_token: gr.OAuthToken,
 
 
 
13
  ):
14
- """
15
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
16
- """
17
- client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
18
 
19
- messages = [{"role": "system", "content": system_message}]
 
 
 
20
 
21
- messages.extend(history)
 
 
 
 
 
 
 
 
 
 
22
 
 
 
23
  messages.append({"role": "user", "content": message})
24
 
25
  response = ""
26
-
27
  for message in client.chat_completion(
28
  messages,
29
  max_tokens=max_tokens,
@@ -35,69 +89,75 @@ def respond(
35
  token = ""
36
  if len(choices) and choices[0].delta.content:
37
  token = choices[0].delta.content
38
-
39
  response += token
40
  yield response
41
- system_prompt="""
42
- You are Sustainable.ai, a friendly, encouraging, and knowledgeable AI assistant. Your sole purpose is to help users discover simple, practical, and Sustainable.ai alternatives to their everyday actions. You are a supportive guide on their eco-journey, never a critic. Your goal is to make sustainability feel accessible and effortless.
43
- Core Objective: When a user describes an action they are taking, your primary function is to respond with a more Sustainable.ai alternative. This alternative must be practical and require minimal extra effort or cost.
44
- Guiding Principles:
45
- 1. Always Be Positive and Supportive: Your tone is your most important feature. You are cheerful, encouraging, and non-judgmental. Frame your suggestions as exciting opportunities, not as corrections. Never use language that could make the user feel guilty, shamed, or accused of doing something "wrong."
46
- * AVOID: "Instead of wastefully driving your car..."
47
- * INSTEAD: "That's a great time to get errands done! If the weather's nice, a quick walk could be a lovely way to..."
48
- 2. Prioritize Practicality and Low Effort: The suggestions you provide must be realistic for the average person. The ideal alternative is a simple swap or a minor adjustment to a routine.
49
- * GOOD EXAMPLES: Using a reusable coffee cup, turning a t-shirt into a cleaning rag, combining errands into one trip, opting for paperless billing.
50
- * BAD EXAMPLES: Installing solar panels, building a compost bin from scratch, buying an expensive electric vehicle, weaving your own cloth.
51
- 3. Provide a "Micro-Why": Briefly and simply explain the benefit of your suggestion. This helps the user feel motivated and informed. Keep it concise.
52
- * Example: "...it helps cut down on single-use plastic." or "...which saves water and energy!"
53
- 4. Acknowledge and Validate: Start your response by acknowledging the user's action in a positive or neutral way. This builds rapport and shows you've understood them.
54
- * User: "I'm throwing out leftover vegetables."
55
- * Your Start: "Cleaning out the fridge can feel so productive! Before those veggies go, have you considered..."
56
- 5. Handling Edge Cases:
57
- * If the User's Action is Already Sustainable.ai: Celebrate it! Offer praise and reinforcement. This is a crucial part of your supportive persona. (e.g., "That's fantastic! Mending clothes is one of the best things we can do for the planet. You're an eco-hero!").
58
- * If No Easy Alternative Exists: Acknowledge that sometimes the conventional way is the most practical. Do not force a difficult or unrealistic suggestion. You can offer a related, but different tip, or simply affirm their action. (e.g., "Sometimes, a disposable diaper is just the most practical choice, and that's completely okay! One easy swap in another area is using reusable cloths instead of paper towels for cleanups.").
59
- * If the Query is Unclear: Ask a gentle, clarifying question.
60
- Example Interactions (Follow this format and tone precisely):
61
- Example 1:
62
- * User: "I'm buying a bottle of water from the vending machine."
63
- * Sustainable.ai: "It's always a good idea to stay hydrated! For a simple swap next time, you could carry a reusable water bottle. It saves you money in the long run and helps reduce plastic waste. Plus, you can fill it up for free!"
64
- Example 2:
65
- * User: "I'm about to throw this glass pasta sauce jar in the trash."
66
- * Sustainable.ai: "Getting every last bit of sauce is an art! Glass jars are fantastic because they're so easy to reuse. After a quick rinse, that jar is perfect for storing leftovers, organizing pens on your desk, or even as a small planter. Itโ€™s a super simple way to give it a second life before recycling."
67
- Example 3:
68
- * User: "Driving to the post office which is about a mile away."
69
- * Sustainable.ai: "Tackling that to-do list is a great feeling! Since it's so close, a brisk walk or a quick bike ride could be a wonderful option. It's a perfect chance to get a little fresh air and sunshine while also cutting down on emissions."
70
- Example 4 (Praise):
71
- * User: "I'm taking my reusable bags to the grocery store."
72
- * Sustainable.ai: "That's amazing! You're a sustainability superstar. Using reusable bags is one of the most impactful and easy habits. Keep up the fantastic work!"
73
- Final Instruction: You are Sustainable.ai. You are a friend, a cheerleader, and a source of simple, positive ideas. Your responses should always leave the user feeling good about themselves and empowered to make small, Sustainable.ai changes.
74
- """
75
 
 
 
 
76
  """
77
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
78
- """
79
- chatbot = gr.ChatInterface(
80
- respond,
81
- type="messages",
82
- additional_inputs=[
83
- gr.Textbox(value=system_prompt, label="System message"),
84
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
85
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
86
- gr.Slider(
87
- minimum=0.1,
88
- maximum=1.0,
89
- value=0.95,
90
- step=0.05,
91
- label="Top-p (nucleus sampling)",
92
- ),
93
- ],
94
- )
95
-
96
- with gr.Blocks() as demo:
97
- with gr.Sidebar():
98
- gr.LoginButton()
99
- chatbot.render()
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  if __name__ == "__main__":
103
  demo.launch()
 
1
+ import os
2
  import gradio as gr
3
  from huggingface_hub import InferenceClient
4
 
5
+ HF_TOKEN = os.environ["HF_TOKEN"]
6
+
7
+ EMISSIONS_FACTORS = {
8
+ "transportation": {
9
+ "car": 2.3,
10
+ "bus": 0.1,
11
+ "train": 0.04,
12
+ "plane": 0.25,
13
+ },
14
+ "food": {
15
+ "meat": 6.0,
16
+ "vegetarian": 1.5,
17
+ "vegan": 1.0,
18
+ }
19
+ }
20
+
21
+ def calculate_footprint(car_km, bus_km, train_km, air_km, meat_meals, vegetarian_meals, vegan_meals):
22
+ transport_emissions = (
23
+ car_km * EMISSIONS_FACTORS["transportation"]["car"] +
24
+ bus_km * EMISSIONS_FACTORS["transportation"]["bus"] +
25
+ train_km * EMISSIONS_FACTORS["transportation"]["train"] +
26
+ air_km * EMISSIONS_FACTORS["transportation"]["plane"]
27
+ )
28
+
29
+ food_emissions = (
30
+ meat_meals * EMISSIONS_FACTORS["food"]["meat"] +
31
+ vegetarian_meals * EMISSIONS_FACTORS["food"]["vegetarian"] +
32
+ vegan_meals * EMISSIONS_FACTORS["food"]["vegan"]
33
+ )
34
+
35
+ total_emissions = transport_emissions + food_emissions
36
+
37
+ stats = {
38
+ "trees": round(total_emissions / 21),
39
+ "flights": round(total_emissions / 500),
40
+ "driving100km": round(total_emissions / 230),
41
+ }
42
+
43
+ return total_emissions, stats
44
 
45
  def respond(
46
  message,
47
  history: list[dict[str, str]],
48
  system_message,
49
+ car_km,
50
+ bus_km,
51
+ train_km,
52
+ air_km,
53
+ meat_meals,
54
+ vegetarian_meals,
55
+ vegan_meals,
56
  ):
57
+ client = InferenceClient(token=HF_TOKEN)
 
 
 
58
 
59
+ footprint, stats = calculate_footprint(
60
+ car_km, bus_km, train_km, air_km,
61
+ meat_meals, vegetarian_meals, vegan_meals
62
+ )
63
 
64
+ custom_prompt = f"""
65
+ This userโ€™s estimated weekly footprint is **{footprint:.1f} kg CO2**.
66
+ Thatโ€™s equivalent to planting about {stats['trees']} trees ๐ŸŒณ or taking {stats['flights']} short flights โœˆ๏ธ.
67
+ Their breakdown includes both transportation and food habits.
68
+ Your job is to guide them with practical, encouraging suggestions to lower this footprint.
69
+ {system_message}
70
+ """
71
+
72
+ max_tokens = 512
73
+ temperature = 0.7
74
+ top_p = 0.95
75
 
76
+ messages = [{"role": "system", "content": custom_prompt}]
77
+ messages.extend(history)
78
  messages.append({"role": "user", "content": message})
79
 
80
  response = ""
 
81
  for message in client.chat_completion(
82
  messages,
83
  max_tokens=max_tokens,
 
89
  token = ""
90
  if len(choices) and choices[0].delta.content:
91
  token = choices[0].delta.content
 
92
  response += token
93
  yield response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
+ system_prompt = """
96
+ You are Sustainable.ai, a friendly, encouraging, and knowledgeable AI assistant...
97
+ (omit full content for brevity โ€“ use your full prompt here)
98
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
+ with gr.Blocks(css="""
101
+ body {
102
+ background: linear-gradient(135deg, #e0f7fa, #f1f8e9);
103
+ }
104
+ .section-card {
105
+ background: white;
106
+ padding: 20px;
107
+ border-radius: 15px;
108
+ box-shadow: 0px 4px 12px rgba(0,0,0,0.1);
109
+ margin-bottom: 20px;
110
+ }
111
+ .title-text {
112
+ text-align: center;
113
+ font-size: 28px;
114
+ font-weight: bold;
115
+ color: #2e7d32;
116
+ }
117
+ .subtitle-text {
118
+ text-align: center;
119
+ font-size: 16px;
120
+ color: #555;
121
+ margin-bottom: 20px;
122
+ }
123
+ """) as demo:
124
+
125
+ with gr.Column():
126
+ gr.HTML("<div class='title-text'>๐ŸŒ Eco Wise AI</div>")
127
+ gr.HTML("<div class='subtitle-text'>Track your weekly habits and chat with your personal sustainability coach ๐ŸŒฑ</div>")
128
+
129
+ with gr.Group(elem_classes="section-card"):
130
+ gr.Markdown("### ๐Ÿš— Transportation (per week)")
131
+ with gr.Row():
132
+ car_input = gr.Number(label="๐Ÿš˜ Car Travel (km)", value=0)
133
+ bus_input = gr.Number(label="๐ŸšŒ Bus Travel (km)", value=0)
134
+ with gr.Row():
135
+ train_input = gr.Number(label="๐Ÿš† Train Travel (km)", value=0)
136
+ air_input = gr.Number(label="โœˆ๏ธ Air Travel (km/month)", value=0)
137
+
138
+
139
+ with gr.Group(elem_classes="section-card"):
140
+ gr.Markdown("### ๐Ÿฝ๏ธ Food Habits (per week)")
141
+ with gr.Row():
142
+ meat_input = gr.Number(label="๐Ÿฅฉ Meat Meals", value=0)
143
+ vegetarian_input = gr.Number(label="๐Ÿฅ— Vegetarian Meals", value=0)
144
+ vegan_input = gr.Number(label="๐ŸŒฑ Vegan Meals", value=0)
145
+
146
+
147
+ chatbot = gr.ChatInterface(
148
+ respond,
149
+ type="messages",
150
+ additional_inputs=[
151
+ gr.Textbox(value=system_prompt, visible=False),
152
+ car_input,
153
+ bus_input,
154
+ train_input,
155
+ air_input,
156
+ meat_input,
157
+ vegetarian_input,
158
+ vegan_input,
159
+ ],
160
+ )
161
 
162
  if __name__ == "__main__":
163
  demo.launch()
tests/test_app.py CHANGED
@@ -14,7 +14,6 @@ def test_respond_function_exists():
14
 
15
  def test_respond_returns_generator():
16
  """respond() should return a generator when called with minimal args."""
17
- # Fake OAuthToken object for testing (since we don't want to call real HF API in CI)
18
  class DummyToken:
19
  token = "dummy"
20
 
@@ -28,5 +27,4 @@ def test_respond_returns_generator():
28
  hf_token=DummyToken(),
29
  )
30
 
31
- # respond() is a generator, not a plain string
32
  assert isinstance(gen, types.GeneratorType)
 
14
 
15
  def test_respond_returns_generator():
16
  """respond() should return a generator when called with minimal args."""
 
17
  class DummyToken:
18
  token = "dummy"
19
 
 
27
  hf_token=DummyToken(),
28
  )
29
 
 
30
  assert isinstance(gen, types.GeneratorType)