wahab5763 commited on
Commit
40bf3e7
·
verified ·
1 Parent(s): 62b98f2

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +206 -0
app.py ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from collections.abc import Generator
3
+ from typing import Any
4
+
5
+ import gradio as gr
6
+ from dotenv import load_dotenv
7
+ from groq import Groq
8
+
9
+ # Loads GROQ_API_KEY from a local .env file when running on your computer.
10
+ # On Hugging Face Spaces, add GROQ_API_KEY under Settings > Secrets.
11
+ load_dotenv()
12
+
13
+ DEFAULT_SYSTEM_PROMPT = (
14
+ "You are a helpful, accurate, and friendly AI assistant. "
15
+ "Answer clearly, use Markdown when helpful, and admit uncertainty when needed."
16
+ )
17
+
18
+ MODEL_CHOICES = [
19
+ "openai/gpt-oss-20b",
20
+ "openai/gpt-oss-120b",
21
+ ]
22
+
23
+ CUSTOM_CSS = """
24
+ .gradio-container {
25
+ max-width: 1050px !important;
26
+ margin: 0 auto !important;
27
+ }
28
+ #app-header {
29
+ text-align: center;
30
+ padding: 12px 0 4px 0;
31
+ }
32
+ #app-subtitle {
33
+ text-align: center;
34
+ opacity: 0.8;
35
+ margin-bottom: 10px;
36
+ }
37
+ footer {
38
+ display: none !important;
39
+ }
40
+ """
41
+
42
+
43
+ def _text_history(history: list[dict[str, Any]]) -> list[dict[str, str]]:
44
+ """Keep only plain-text user and assistant messages for the Groq API."""
45
+ cleaned: list[dict[str, str]] = []
46
+
47
+ for item in history or []:
48
+ role = item.get("role")
49
+ content = item.get("content")
50
+
51
+ if role in {"user", "assistant"} and isinstance(content, str):
52
+ cleaned.append({"role": role, "content": content})
53
+
54
+ return cleaned
55
+
56
+
57
+ def chat_with_groq(
58
+ message: str,
59
+ history: list[dict[str, Any]],
60
+ model: str,
61
+ system_prompt: str,
62
+ temperature: float,
63
+ max_tokens: int,
64
+ ) -> Generator[str, None, None]:
65
+ """Stream a Groq response to the Gradio chat interface."""
66
+ api_key = os.getenv("GROQ_API_KEY")
67
+
68
+ if not api_key:
69
+ yield (
70
+ "### Missing API key\n\n"
71
+ "Add a Hugging Face Space secret named `GROQ_API_KEY`, then restart the Space."
72
+ )
73
+ return
74
+
75
+ user_message = (message or "").strip()
76
+ if not user_message:
77
+ yield "Please enter a message."
78
+ return
79
+
80
+ selected_model = model if model in MODEL_CHOICES else MODEL_CHOICES[0]
81
+ instructions = (system_prompt or "").strip() or DEFAULT_SYSTEM_PROMPT
82
+
83
+ messages: list[dict[str, str]] = [
84
+ {"role": "system", "content": instructions},
85
+ *_text_history(history),
86
+ {"role": "user", "content": user_message},
87
+ ]
88
+
89
+ try:
90
+ client = Groq(api_key=api_key)
91
+ stream = client.chat.completions.create(
92
+ model=selected_model,
93
+ messages=messages,
94
+ temperature=float(temperature),
95
+ max_completion_tokens=int(max_tokens),
96
+ stream=True,
97
+ )
98
+
99
+ response = ""
100
+ for chunk in stream:
101
+ delta = chunk.choices[0].delta.content
102
+ if delta:
103
+ response += delta
104
+ yield response
105
+
106
+ if not response:
107
+ yield "The model returned an empty response. Please try again."
108
+
109
+ except Exception as error:
110
+ # Show a useful message without exposing the API key or other secrets.
111
+ error_name = type(error).__name__
112
+ yield (
113
+ "### Request failed\n\n"
114
+ f"`{error_name}`: {error}\n\n"
115
+ "Check your Groq API key, model access, account limits, and network connection."
116
+ )
117
+
118
+
119
+ with gr.Blocks(title="Groq AI Chat") as demo:
120
+ gr.Markdown("# ⚡ Groq AI Chat", elem_id="app-header")
121
+ gr.Markdown(
122
+ "A fast, streaming chatbot powered by Groq and built with Gradio.",
123
+ elem_id="app-subtitle",
124
+ )
125
+
126
+ with gr.Accordion("Chat settings", open=False):
127
+ model_input = gr.Dropdown(
128
+ choices=MODEL_CHOICES,
129
+ value=MODEL_CHOICES[0],
130
+ label="Groq model",
131
+ info="GPT-OSS 20B is faster; GPT-OSS 120B is stronger for complex tasks.",
132
+ )
133
+ system_prompt_input = gr.Textbox(
134
+ value=DEFAULT_SYSTEM_PROMPT,
135
+ label="System prompt",
136
+ lines=3,
137
+ )
138
+ with gr.Row():
139
+ temperature_input = gr.Slider(
140
+ minimum=0.0,
141
+ maximum=2.0,
142
+ value=0.7,
143
+ step=0.1,
144
+ label="Temperature",
145
+ )
146
+ max_tokens_input = gr.Slider(
147
+ minimum=128,
148
+ maximum=4096,
149
+ value=1024,
150
+ step=128,
151
+ label="Maximum response tokens",
152
+ )
153
+
154
+ chatbot = gr.Chatbot(
155
+ label="Conversation",
156
+ placeholder="Ask anything to begin the conversation.",
157
+ height=520,
158
+ )
159
+
160
+ gr.ChatInterface(
161
+ fn=chat_with_groq,
162
+ chatbot=chatbot,
163
+ additional_inputs=[
164
+ model_input,
165
+ system_prompt_input,
166
+ temperature_input,
167
+ max_tokens_input,
168
+ ],
169
+ examples=[
170
+ [
171
+ "Explain artificial intelligence in simple words.",
172
+ MODEL_CHOICES[0],
173
+ DEFAULT_SYSTEM_PROMPT,
174
+ 0.7,
175
+ 1024,
176
+ ],
177
+ [
178
+ "Write a professional email requesting a meeting.",
179
+ MODEL_CHOICES[0],
180
+ DEFAULT_SYSTEM_PROMPT,
181
+ 0.7,
182
+ 1024,
183
+ ],
184
+ [
185
+ "Create a beginner-friendly Python learning plan.",
186
+ MODEL_CHOICES[1],
187
+ DEFAULT_SYSTEM_PROMPT,
188
+ 0.5,
189
+ 1536,
190
+ ],
191
+ ],
192
+ editable=True,
193
+ save_history=True,
194
+ flagging_mode="never",
195
+ api_visibility="private",
196
+ concurrency_limit=5,
197
+ fill_height=True,
198
+ fill_width=True,
199
+ )
200
+
201
+
202
+ if __name__ == "__main__":
203
+ demo.queue(default_concurrency_limit=5).launch(
204
+ theme=gr.themes.Soft(),
205
+ css=CUSTOM_CSS,
206
+ )