Eyadddddddd commited on
Commit
0c1db11
·
verified ·
1 Parent(s): 982f5f0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -78
app.py CHANGED
@@ -8,10 +8,15 @@ from PIL import Image
8
  # =========================
9
 
10
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
 
11
  if not GROQ_API_KEY:
12
- raise RuntimeError("⚠️ GROQ_API_KEY is missing! Add it in Hugging Face Settings Secrets.")
13
 
14
- client = Groq(api_key=GROQ_API_KEY)
 
 
 
 
15
 
16
  DEFAULT_MODEL = "llama-3.1-8b-instant"
17
 
@@ -23,7 +28,7 @@ MODE_PROMPTS = {
23
  }
24
 
25
  # =========================
26
- # ASCII CONVERSION (FIXED)
27
  # =========================
28
 
29
  def image_to_ascii(image_path, output_width=100):
@@ -32,7 +37,7 @@ def image_to_ascii(image_path, output_width=100):
32
  img = Image.open(image_path).convert("L")
33
  w, h = img.size
34
  if w == 0:
35
- return "[Error converting image to ASCII: image width is zero]"
36
  ratio = h / w
37
  new_height = max(1, int(output_width * ratio * 0.55))
38
  img = img.resize((output_width, new_height))
@@ -47,80 +52,55 @@ def image_to_ascii(image_path, output_width=100):
47
  return f"[Error converting image to ASCII: {e}]"
48
 
49
  # =========================
50
- # CHAT FUNCTION (WITH HISTORY & MESSAGE SANITIZATION)
51
  # =========================
52
 
53
  def chat_fn(message, history, mode="Normal Chat", model=DEFAULT_MODEL, image=None, include_ascii=False):
54
  try:
55
- # Start with a validated system prompt
 
 
 
56
  system_prompt = MODE_PROMPTS.get(mode, MODE_PROMPTS["Normal Chat"])
57
  messages = [{"role": "system", "content": str(system_prompt).strip()}]
58
 
59
- # SAFELY process history only accept valid [user, assistant] pairs
60
  if isinstance(history, list):
61
- for pair in history:
62
- if isinstance(pair, (list, tuple)) and len(pair) == 2:
63
- user_msg, assistant_msg = pair
64
-
65
- if isinstance(user_msg, str) and user_msg.strip():
66
- messages.append({
67
- "role": "user",
68
- "content": user_msg.strip()
69
- })
70
-
71
- if isinstance(assistant_msg, str) and assistant_msg.strip():
72
- messages.append({
73
- "role": "assistant",
74
- "content": assistant_msg.strip()
75
- })
76
-
77
- # If image uploaded + toggle ON → convert to ASCII safely
78
  if image and include_ascii:
79
  try:
80
- ascii_art = image_to_ascii(image.name)
 
81
  except Exception:
82
- ascii_art = "[Error converting image to ASCII]"
83
-
84
- safe_message_text = str(message).strip() if message else ""
85
- message = f"[ASCII Art from Uploaded Image]\n{ascii_art}\n\nUser message: {safe_message_text}"
86
-
87
- # Ensure current message is always a clean string
88
- current_user_content = str(message).strip() if message else ""
89
- messages.append({
90
- "role": "user",
91
- "content": current_user_content
92
- })
93
-
94
- # Final validation: ensure every message is a dict with role + content
95
- validated_messages = []
96
- for m in messages:
97
- if not isinstance(m, dict):
98
- continue
99
- role = m.get("role")
100
- content = m.get("content")
101
- if role in ("system", "user", "assistant") and isinstance(content, str):
102
- validated_messages.append({"role": role, "content": content})
103
-
104
- if not validated_messages:
105
- return "⚠️ Error: No valid messages to send."
106
-
107
- # Call Groq
108
  response = client.chat.completions.create(
109
  model=model,
110
- messages=validated_messages
111
  )
112
 
113
- # Extract assistant reply safely
114
- try:
115
- return response.choices[0].message.content
116
- except Exception:
117
- return "⚠️ Error: Unexpected response format from the model."
118
 
119
  except Exception as e:
120
  return f"⚠️ Error: {str(e)}"
121
 
122
  # =========================
123
- # UI (FULLY FIXED)
124
  # =========================
125
 
126
  with gr.Blocks(title="🦙 NeoHelper — Eyad’s Groq-powered Assistant") as demo:
@@ -144,7 +124,8 @@ with gr.Blocks(title="🦙 NeoHelper — Eyad’s Groq-powered Assistant") as de
144
  label="Model"
145
  )
146
 
147
- chatbot = gr.Chatbot(height=500)
 
148
 
149
  with gr.Row():
150
  user_input = gr.Textbox(
@@ -158,35 +139,29 @@ with gr.Blocks(title="🦙 NeoHelper — Eyad’s Groq-powered Assistant") as de
158
  ascii_toggle = gr.Checkbox(label="Convert image to ASCII", value=False)
159
 
160
  def on_send(msg, history, mode, model, image, include_ascii):
161
- # Normalize history to a list if None
162
  if history is None:
163
  history = []
164
-
165
- # Clean malformed history entries BEFORE sending to chat_fn
166
- clean_history = []
167
- for pair in history:
168
- if isinstance(pair, (list, tuple)) and len(pair) == 2:
169
- u, a = pair
170
- if isinstance(u, str) and isinstance(a, str):
171
- clean_history.append([u.strip(), a.strip()])
172
- history = clean_history
173
-
174
- # Ensure msg is a string
175
  user_msg = str(msg).strip() if msg else ""
176
-
177
- # Call chat function
178
  reply = chat_fn(
179
  user_msg,
180
- history,
181
  mode,
182
  model,
183
  image,
184
  include_ascii
185
  )
186
-
187
- # Append sanitized strings to history
188
- safe_reply = str(reply).strip() if reply else ""
189
- history.append([user_msg, safe_reply])
 
 
 
190
  return history, ""
191
 
192
  send_btn.click(
 
8
  # =========================
9
 
10
  GROQ_API_KEY = os.getenv("GROQ_API_KEY")
11
+ # Ideally, use a robust check or default to None if handling locally
12
  if not GROQ_API_KEY:
13
+ print("⚠️ GROQ_API_KEY is missing! Ensure it is set in your environment or Secrets.")
14
 
15
+ try:
16
+ client = Groq(api_key=GROQ_API_KEY)
17
+ except Exception as e:
18
+ client = None
19
+ print(f"Error initializing Groq client: {e}")
20
 
21
  DEFAULT_MODEL = "llama-3.1-8b-instant"
22
 
 
28
  }
29
 
30
  # =========================
31
+ # ASCII CONVERSION
32
  # =========================
33
 
34
  def image_to_ascii(image_path, output_width=100):
 
37
  img = Image.open(image_path).convert("L")
38
  w, h = img.size
39
  if w == 0:
40
+ return "[Error: image width is zero]"
41
  ratio = h / w
42
  new_height = max(1, int(output_width * ratio * 0.55))
43
  img = img.resize((output_width, new_height))
 
52
  return f"[Error converting image to ASCII: {e}]"
53
 
54
  # =========================
55
+ # CHAT FUNCTION (FIXED FOR MESSAGES FORMAT)
56
  # =========================
57
 
58
  def chat_fn(message, history, mode="Normal Chat", model=DEFAULT_MODEL, image=None, include_ascii=False):
59
  try:
60
+ if not client:
61
+ return "⚠️ Error: Groq client not initialized. Check API Key."
62
+
63
+ # 1. Prepare System Prompt
64
  system_prompt = MODE_PROMPTS.get(mode, MODE_PROMPTS["Normal Chat"])
65
  messages = [{"role": "system", "content": str(system_prompt).strip()}]
66
 
67
+ # 2. Add History (Now in Dictionary Format)
68
  if isinstance(history, list):
69
+ for msg in history:
70
+ if isinstance(msg, dict) and "role" in msg and "content" in msg:
71
+ messages.append(msg)
72
+
73
+ # 3. Handle Image / Current Message
74
+ safe_message_text = str(message).strip() if message else ""
75
+
 
 
 
 
 
 
 
 
 
 
76
  if image and include_ascii:
77
  try:
78
+ ascii_art = image_to_ascii(image)
79
+ final_content = f"[ASCII Art from Uploaded Image]\n{ascii_art}\n\nUser message: {safe_message_text}"
80
  except Exception:
81
+ final_content = safe_message_text
82
+ else:
83
+ final_content = safe_message_text
84
+
85
+ # Append current user message
86
+ if final_content:
87
+ messages.append({"role": "user", "content": final_content})
88
+ else:
89
+ return "⚠️ Error: No message content provided."
90
+
91
+ # 4. Call Groq API
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  response = client.chat.completions.create(
93
  model=model,
94
+ messages=messages
95
  )
96
 
97
+ return response.choices[0].message.content
 
 
 
 
98
 
99
  except Exception as e:
100
  return f"⚠️ Error: {str(e)}"
101
 
102
  # =========================
103
+ # UI (FIXED)
104
  # =========================
105
 
106
  with gr.Blocks(title="🦙 NeoHelper — Eyad’s Groq-powered Assistant") as demo:
 
124
  label="Model"
125
  )
126
 
127
+ # FIX 1: Set type="messages" to match the data format Gradio expects
128
+ chatbot = gr.Chatbot(height=500, type="messages")
129
 
130
  with gr.Row():
131
  user_input = gr.Textbox(
 
139
  ascii_toggle = gr.Checkbox(label="Convert image to ASCII", value=False)
140
 
141
  def on_send(msg, history, mode, model, image, include_ascii):
142
+ # Initialize history if empty
143
  if history is None:
144
  history = []
145
+
146
+ # User message string
 
 
 
 
 
 
 
 
 
147
  user_msg = str(msg).strip() if msg else ""
148
+
149
+ # Get response
150
  reply = chat_fn(
151
  user_msg,
152
+ history, # Pass history as is (list of dicts)
153
  mode,
154
  model,
155
  image,
156
  include_ascii
157
  )
158
+
159
+ # FIX 2: Append dictionaries {role, content} instead of lists [user, bot]
160
+ if user_msg:
161
+ history.append({"role": "user", "content": user_msg})
162
+
163
+ history.append({"role": "assistant", "content": str(reply)})
164
+
165
  return history, ""
166
 
167
  send_btn.click(