mgbam commited on
Commit
d298f2f
·
verified ·
1 Parent(s): 8f18936

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +66 -198
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import re
2
  from http import HTTPStatus
3
  from typing import Dict, List, Optional, Tuple
@@ -15,12 +16,10 @@ from bs4 import BeautifulSoup
15
  import html2text
16
  import json
17
  import time
18
- import os
19
 
20
  import gradio as gr
21
  from huggingface_hub import InferenceClient
22
  from tavily import TavilyClient
23
- import openai
24
 
25
  # Gradio supported languages for syntax highlighting
26
  GRADIO_SUPPORTED_LANGUAGES = [
@@ -115,41 +114,45 @@ Removing the paragraph...
115
 
116
  # Available models
117
  AVAILABLE_MODELS = [
 
 
 
 
 
118
  {
119
  "name": "DeepSeek V3",
120
  "id": "deepseek-ai/DeepSeek-V3-0324",
121
- "description": "DeepSeek V3 model for code generation", "provider": "deepseek"
122
  },
123
  {
124
- "name": "DeepSeek R1",
125
  "id": "deepseek-ai/DeepSeek-R1-0528",
126
- "description": "DeepSeek R1 model for code generation", "provider": "deepseek"
127
  },
128
  {
129
- # "name": "GPT-4o-mini",
130
- # "id": "gpt-4o-mini",
131
- # "description": "OpenAI GPT-4o-mini model for code generation and general tasks",
132
- # "provider": "openai"
133
- #}, # Commented out to avoid requiring extra setup for all users
134
- #{
135
- "name": "Gemini 1.5 Pro",
136
- "id": "gemini-1.5-pro-latest",
137
- "description": "Google Gemini 1.5 Pro model for code generation and general tasks", "provider": "gemini"
138
  },
139
  {
140
- "name": "GPT-4o",
141
- "id": "gpt-4o",
142
- "description": "OpenAI GPT-4o model for code generation and general tasks", "provider": "openai"
143
  },
144
  {
145
  "name": "Qwen3-235B-A22B",
146
  "id": "Qwen/Qwen3-235B-A22B",
147
- "description": "Qwen3-235B-A22B model for code generation and general tasks", "provider": "huggingface"
148
  },
149
  {
150
- "name": "GLM-4.1V-9B-Thinking",
151
- "id": "THUDM/GLM-4.1V-9B-Thinking",
152
- "description": "GLM-4.1V-9B-Thinking model for multimodal code generation with image support",
 
 
 
 
 
153
  }
154
  ]
155
 
@@ -213,51 +216,16 @@ DEMO_LIST = [
213
  ]
214
 
215
  # HF Inference Client
216
- HF_TOKEN = os.getenv("HF_TOKEN")
217
- OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
218
- GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
219
- DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY")
220
 
221
  def get_inference_client(model_id):
222
- """Return an appropriate client based on model_id and configured provider."""
223
- model_info = next((m for m in AVAILABLE_MODELS if m["id"] == model_id), None)
224
- if not model_info:
225
- raise ValueError(f"Model with id '{model_id}' not found.")
226
-
227
- provider = model_info.get("provider")
228
-
229
- if provider == "deepseek":
230
- if not DEEPSEEK_API_KEY:
231
- raise ValueError("DEEPSEEK_API_KEY environment variable not set.")
232
- return "deepseek_client" # Return a string placeholder, logic is handled in generation_code
233
-
234
- if provider == "groq":
235
- return InferenceClient(
236
- provider="groq",
237
- api_key=HF_TOKEN, # Groq uses HF token as well
238
- bill_to="huggingface" # Assuming billing through HF for Groq
239
- )
240
- elif provider == "huggingface":
241
- if not HF_TOKEN:
242
- raise ValueError("HF_TOKEN environment variable not set for Hugging Face models.")
243
- return InferenceClient(
244
- provider="auto", # Use HF's auto provider for other HF models
245
- api_key=HF_TOKEN,
246
- bill_to="huggingface"
247
- )
248
- elif provider == "openai":
249
- if not OPENAI_API_KEY:
250
- raise ValueError("OPENAI_API_KEY environment variable not set.")
251
- openai.api_key = OPENAI_API_KEY
252
- return openai
253
- elif provider == "gemini":
254
- if not GEMINI_API_KEY:
255
- raise ValueError("GEMINI_API_KEY environment variable not set.")
256
- import google.generativeai as genai
257
- genai.configure(api_key=GEMINI_API_KEY)
258
- return genai
259
- else:
260
- raise ValueError(f"Unsupported provider: {provider}")
261
 
262
  # Type definitions
263
  History = List[Tuple[str, str]]
@@ -283,7 +251,7 @@ def history_to_messages(history: History, system: str) -> Messages:
283
  text_content = ""
284
  for item in user_content:
285
  if isinstance(item, dict) and item.get("type") == "text":
286
- text_content += str(item.get("text", ""))
287
  user_content = text_content if text_content else str(user_content)
288
 
289
  messages.append({'role': 'user', 'content': user_content})
@@ -300,7 +268,7 @@ def messages_to_history(messages: Messages) -> Tuple[str, History]:
300
  text_content = ""
301
  for item in user_content:
302
  if isinstance(item, dict) and item.get("type") == "text":
303
- text_content += str(item.get("text", ""))
304
  user_content = text_content if text_content else str(user_content)
305
 
306
  history.append([user_content, r['content']])
@@ -315,7 +283,7 @@ def history_to_chatbot_messages(history: History) -> List[Dict[str, str]]:
315
  text_content = ""
316
  for item in user_msg:
317
  if isinstance(item, dict) and item.get("type") == "text":
318
- text_content += str(item.get("text", ""))
319
  user_msg = text_content if text_content else str(user_msg)
320
 
321
  messages.append({"role": "user", "content": user_msg})
@@ -1011,139 +979,41 @@ This will help me create a better design for you."""
1011
  else:
1012
  messages.append({'role': 'user', 'content': enhanced_query})
1013
  try:
1014
- if _current_model["provider"] == "openai":
1015
- # Use OpenAI client
1016
- stream = client.chat.completions.create(
1017
- model=_current_model["id"],
1018
- messages=[{"role": m["role"], "content": m["content"]} for m in messages],
1019
- stream=True,
1020
- max_tokens=5000,
1021
- )
1022
-
1023
- content = ""
1024
- for chunk in stream:
1025
- if chunk.choices[0].delta.content:
1026
- content += chunk.choices[0].delta.content
1027
- clean_code = remove_code_block(content)
1028
- if has_existing_html:
1029
- # ... (rest of the modification logic) ...
1030
- if clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html"):
1031
- yield {
1032
- code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
1033
- history_output: history_to_chatbot_messages(_history),
1034
- sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1035
- }
1036
- else:
1037
- last_html = _history[-1][1] if _history else ""
1038
- modified_html = apply_search_replace_changes(last_html, clean_code)
1039
- clean_html = remove_code_block(modified_html)
1040
- yield {
1041
- code_output: gr.update(value=clean_html, language=get_gradio_language(language)),
1042
- history_output: history_to_chatbot_messages(_history),
1043
- sandbox: send_to_sandbox(clean_html) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1044
- }
1045
- else:
1046
  yield {
1047
  code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
1048
  history_output: history_to_chatbot_messages(_history),
1049
  sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1050
  }
1051
- elif _current_model["provider"] == "gemini":
1052
- # Use Gemini client (assumes you've adapted the message format)
1053
- chat = client.GenerativeModel(_current_model["id"]).start_chat(history=[]) # Assuming it uses history
1054
- for message in messages[1:]:
1055
- if message["role"] == "user":
1056
- chat.send_message(message["content"])
1057
- elif message["role"] == "assistant":
1058
- chat.send_message(message["content"])
1059
-
1060
- response = chat.send_message(messages[-1]["content"], stream=True)
1061
- content = ""
1062
- for chunk in response:
1063
- content += chunk.text
1064
- clean_code = remove_code_block(content)
1065
- if has_existing_html:
1066
- # ... (rest of the modification logic) ...
1067
- if clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html"):
1068
- yield {
1069
- code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
1070
- history_output: history_to_chatbot_messages(_history),
1071
- sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1072
- }
1073
- else:
1074
- last_html = _history[-1][1] if _history else ""
1075
- modified_html = apply_search_replace_changes(last_html, clean_code)
1076
- clean_html = remove_code_block(modified_html)
1077
- yield {
1078
- code_output: gr.update(value=clean_html, language=get_gradio_language(language)),
1079
- history_output: history_to_chatbot_messages(_history),
1080
- sandbox: send_to_sandbox(clean_html) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1081
- }
1082
  else:
1083
- yield {
1084
- code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
1085
- history_output: history_to_chatbot_messages(_history),
1086
- sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1087
- }
1088
- elif _current_model["provider"] == "deepseek":
1089
- # Use requests to call Deepseek API directly
1090
- url = "https://api.deepseek.com/v1/chat/completions"
1091
- headers = {
1092
- "Authorization": f"Bearer {DEEPSEEK_API_KEY}",
1093
- "Content-Type": "application/json"
1094
- }
1095
- payload = {
1096
- "model": _current_model["id"], # Use the full model ID from AVAILABLE_MODELS
1097
- "messages": [{"role": m["role"], "content": m["content"]} for m in messages],
1098
- "stream": True,
1099
- "max_tokens": 5000
1100
- }
1101
-
1102
- response = requests.post(url, headers=headers, json=payload, stream=True)
1103
- response.raise_for_status()
1104
-
1105
- content = ""
1106
- for line in response.iter_lines():
1107
- if line:
1108
- line_str = line.decode('utf-8')
1109
- if line_str.startswith('data: '):
1110
- json_data = line_str[6:]
1111
- if json_data.strip() != '[DONE]':
1112
- chunk = json.loads(json_data)
1113
- if chunk['choices'][0]['delta'].get('content'):
1114
- content += chunk['choices'][0]['delta']['content']
1115
- clean_code = remove_code_block(content)
1116
- yield {
1117
- code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
1118
- history_output: history_to_chatbot_messages(_history),
1119
- sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1120
- }
1121
-
1122
- else:
1123
- # Use Hugging Face Inference Client (or Groq) for other models
1124
- completion = client.chat.completions.create(
1125
- model=_current_model["id"],
1126
- messages=messages,
1127
- stream=True,
1128
- max_tokens=5000
1129
- )
1130
-
1131
- content = ""
1132
- for chunk in completion:
1133
- if chunk.choices[0].delta.content:
1134
- content += chunk.choices[0].delta.content
1135
- clean_code = remove_code_block(content)
1136
- if has_existing_html:
1137
- # ... (rest of the modification logic) ...
1138
- if clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html"):
1139
- yield {
1140
- code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
1141
- history_output: history_to_chatbot_messages(_history),
1142
- sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1143
- }
1144
- else:
1145
- last_html = _history[-1][1] if _history else ""
1146
- modified_html = apply_search_replace_changes(last_html, clean_code)
1147
  # Handle response based on whether this is a modification or new generation
1148
  if has_existing_html:
1149
  # Fallback: If the model returns a full HTML file, use it directly
@@ -1272,12 +1142,10 @@ with gr.Blocks(
1272
  outputs=input
1273
  )
1274
  if not tavily_client:
1275
- tavily_status = gr.Markdown("⚠️ Web search unavailable. Set TAVILY_API_KEY.", visible=True)
1276
  else:
1277
- tavily_status = gr.Markdown("✅ Web search available", visible=True)
1278
  model_display = gr.Markdown(f"**Model:** {AVAILABLE_MODELS[0]['name']}", visible=True) # Moonshot Kimi-K2
1279
-
1280
-
1281
  def on_model_change(model_name):
1282
  for m in AVAILABLE_MODELS:
1283
  if m['name'] == model_name:
 
1
+ import os
2
  import re
3
  from http import HTTPStatus
4
  from typing import Dict, List, Optional, Tuple
 
16
  import html2text
17
  import json
18
  import time
 
19
 
20
  import gradio as gr
21
  from huggingface_hub import InferenceClient
22
  from tavily import TavilyClient
 
23
 
24
  # Gradio supported languages for syntax highlighting
25
  GRADIO_SUPPORTED_LANGUAGES = [
 
114
 
115
  # Available models
116
  AVAILABLE_MODELS = [
117
+ {
118
+ "name": "Moonshot Kimi-K2",
119
+ "id": "moonshotai/Kimi-K2-Instruct",
120
+ "description": "Moonshot AI Kimi-K2-Instruct model for code generation and general tasks"
121
+ },
122
  {
123
  "name": "DeepSeek V3",
124
  "id": "deepseek-ai/DeepSeek-V3-0324",
125
+ "description": "DeepSeek V3 model for code generation"
126
  },
127
  {
128
+ "name": "DeepSeek R1",
129
  "id": "deepseek-ai/DeepSeek-R1-0528",
130
+ "description": "DeepSeek R1 model for code generation"
131
  },
132
  {
133
+ "name": "ERNIE-4.5-VL",
134
+ "id": "baidu/ERNIE-4.5-VL-424B-A47B-Base-PT",
135
+ "description": "ERNIE-4.5-VL model for multimodal code generation with image support"
 
 
 
 
 
 
136
  },
137
  {
138
+ "name": "MiniMax M1",
139
+ "id": "MiniMaxAI/MiniMax-M1-80k",
140
+ "description": "MiniMax M1 model for code generation and general tasks"
141
  },
142
  {
143
  "name": "Qwen3-235B-A22B",
144
  "id": "Qwen/Qwen3-235B-A22B",
145
+ "description": "Qwen3-235B-A22B model for code generation and general tasks"
146
  },
147
  {
148
+ "name": "SmolLM3-3B",
149
+ "id": "HuggingFaceTB/SmolLM3-3B",
150
+ "description": "SmolLM3-3B model for code generation and general tasks"
151
+ },
152
+ {
153
+ "name": "GLM-4.1V-9B-Thinking",
154
+ "id": "THUDM/GLM-4.1V-9B-Thinking",
155
+ "description": "GLM-4.1V-9B-Thinking model for multimodal code generation with image support"
156
  }
157
  ]
158
 
 
216
  ]
217
 
218
  # HF Inference Client
219
+ HF_TOKEN = os.getenv('HF_TOKEN')
 
 
 
220
 
221
  def get_inference_client(model_id):
222
+ """Return an InferenceClient with provider based on model_id."""
223
+ provider = "groq" if model_id == "moonshotai/Kimi-K2-Instruct" else "auto"
224
+ return InferenceClient(
225
+ provider=provider,
226
+ api_key=HF_TOKEN,
227
+ bill_to="huggingface"
228
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
 
230
  # Type definitions
231
  History = List[Tuple[str, str]]
 
251
  text_content = ""
252
  for item in user_content:
253
  if isinstance(item, dict) and item.get("type") == "text":
254
+ text_content += item.get("text", "")
255
  user_content = text_content if text_content else str(user_content)
256
 
257
  messages.append({'role': 'user', 'content': user_content})
 
268
  text_content = ""
269
  for item in user_content:
270
  if isinstance(item, dict) and item.get("type") == "text":
271
+ text_content += item.get("text", "")
272
  user_content = text_content if text_content else str(user_content)
273
 
274
  history.append([user_content, r['content']])
 
283
  text_content = ""
284
  for item in user_msg:
285
  if isinstance(item, dict) and item.get("type") == "text":
286
+ text_content += item.get("text", "")
287
  user_msg = text_content if text_content else str(user_msg)
288
 
289
  messages.append({"role": "user", "content": user_msg})
 
979
  else:
980
  messages.append({'role': 'user', 'content': enhanced_query})
981
  try:
982
+ completion = client.chat.completions.create(
983
+ model=_current_model["id"],
984
+ messages=messages,
985
+ stream=True,
986
+ max_tokens=5000
987
+ )
988
+ content = ""
989
+ for chunk in completion:
990
+ if chunk.choices[0].delta.content:
991
+ content += chunk.choices[0].delta.content
992
+ clean_code = remove_code_block(content)
993
+ search_status = " (with web search)" if enable_search and tavily_client else ""
994
+ if has_existing_html:
995
+ # Fallback: If the model returns a full HTML file, use it directly
996
+ if clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
997
  yield {
998
  code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
999
  history_output: history_to_chatbot_messages(_history),
1000
  sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1001
  }
1002
+ else:
1003
+ last_html = _history[-1][1] if _history else ""
1004
+ modified_html = apply_search_replace_changes(last_html, clean_code)
1005
+ clean_html = remove_code_block(modified_html)
1006
+ yield {
1007
+ code_output: gr.update(value=clean_html, language=get_gradio_language(language)),
1008
+ history_output: history_to_chatbot_messages(_history),
1009
+ sandbox: send_to_sandbox(clean_html) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1010
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1011
  else:
1012
+ yield {
1013
+ code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
1014
+ history_output: history_to_chatbot_messages(_history),
1015
+ sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1016
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1017
  # Handle response based on whether this is a modification or new generation
1018
  if has_existing_html:
1019
  # Fallback: If the model returns a full HTML file, use it directly
 
1142
  outputs=input
1143
  )
1144
  if not tavily_client:
1145
+ gr.Markdown("⚠️ Web search unavailable", visible=True)
1146
  else:
1147
+ gr.Markdown("✅ Web search available", visible=True)
1148
  model_display = gr.Markdown(f"**Model:** {AVAILABLE_MODELS[0]['name']}", visible=True) # Moonshot Kimi-K2
 
 
1149
  def on_model_change(model_name):
1150
  for m in AVAILABLE_MODELS:
1151
  if m['name'] == model_name: