aiqcamp commited on
Commit
03f48f0
Β·
verified Β·
1 Parent(s): 494ca26

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +267 -377
app.py CHANGED
@@ -1,421 +1,311 @@
 
 
 
 
1
  import gradio as gr
2
- import numpy as np
3
- import random
4
- import torch
5
- from diffusers import DiffusionPipeline
6
- import spaces
7
- # κΈ°λ³Έ μ„€μ •
8
- dtype = torch.bfloat16
9
- device = "cuda" if torch.cuda.is_available() else "cpu"
10
 
11
- # λͺ¨λΈ λ‘œλ“œ
12
- pipe = DiffusionPipeline.from_pretrained(
13
- "black-forest-labs/FLUX.1-schnell",
14
- torch_dtype=dtype
15
- ).to(device)
16
 
17
- MAX_SEED = np.iinfo(np.int32).max
18
- MAX_IMAGE_SIZE = 2048
 
 
 
 
 
 
 
19
 
20
- # Enhanced examples with more detailed prompts and specific styling
21
- EXAMPLES = [
22
- {
23
- "title": "Knowledge Tree",
24
- "prompt": """A handrawn colorful mind map diagram, educational style, vibrant colors, clear hierarchy, golden ratio layout.
25
- KNOWLEDGE
26
- β”œβ”€β”€ ACQUISITION [Brain with Lightning ~60px]
27
- β”‚ β”œβ”€β”€ READING [Open Book with Glow]
28
- β”‚ β”œβ”€β”€ PRACTICE [Hands-on Tools]
29
- β”‚ └── OBSERVATION [Eye with Magnifier]
30
- β”œβ”€β”€ PROCESSING [Gear Network ~50px]
31
- β”‚ β”œβ”€β”€ ANALYSIS [Graph Trending Up]
32
- β”‚ └── SYNTHESIS [Puzzle Pieces]
33
- β”œβ”€β”€ RETENTION [Memory Chip ~45px]
34
- β”‚ β”œβ”€β”€ SHORT-TERM [Quick Flash]
35
- β”‚ └── LONG-TERM [Solid Archive]
36
- └── APPLICATION
37
- β”œβ”€β”€ CREATION [Artist Palette]
38
- └── INNOVATION [Lightbulb Constellation]""",
39
- "width": 1024,
40
- "height": 1024
41
- },
42
- {
43
- "title": "Digital Transformation",
44
- "prompt": """A handrawn colorful mind map diagram, tech-focused style, neon accents, circuit board patterns.
45
- DIGITAL TRANSFORM
46
- β”œβ”€β”€ CLOUD [Cloud with Data Rain ~55px]
47
- β”‚ β”œβ”€β”€ STORAGE [Database Cluster]
48
- β”‚ └── COMPUTING [Server Array]
49
- β”œβ”€β”€ AUTOMATION [Robot Arm ~50px]
50
- β”‚ β”œβ”€β”€ WORKFLOWS [Flowchart]
51
- β”‚ └── AI/ML [Neural Network]
52
- β”œβ”€β”€ SECURITY [Shield Matrix ~45px]
53
- β”‚ β”œβ”€β”€ ENCRYPTION [Lock Code]
54
- β”‚ └── MONITORING [Radar Screen]
55
- └── INTEGRATION
56
- β”œβ”€β”€ APIS [Puzzle Connect]
57
- └── MICROSERVICES [Building Blocks]""",
58
- "width": 1024,
59
- "height": 1024
60
- },
61
- {
62
- "title": "Creative Process",
63
- "prompt": """A handrawn colorful mind map diagram, artistic style, watercolor effects, flowing connections.
64
- CREATIVITY
65
- β”œβ”€β”€ INSPIRATION [Constellation Stars ~60px]
66
- β”‚ β”œβ”€β”€ NATURE [Organic Patterns]
67
- β”‚ └── CULTURE [Global Icons]
68
- β”œβ”€β”€ IDEATION [Floating Bubbles ~50px]
69
- β”‚ β”œβ”€β”€ BRAINSTORM [Thunder Cloud]
70
- β”‚ └── REFINEMENT [Diamond Polish]
71
- β”œβ”€β”€ EXECUTION [Artist Tools ~45px]
72
- β”‚ β”œβ”€β”€ TECHNIQUE [Skilled Hands]
73
- β”‚ └── MEDIUM [Palette Mix]
74
- └── PRESENTATION
75
- β”œβ”€β”€ GALLERY [Frame Display]
76
- └── FEEDBACK [Echo Ripples]""",
77
- "width": 1024,
78
- "height": 1024
79
- },
80
- {
81
- "title": "Future Cities",
82
- "prompt": """A handrawn colorful mind map diagram, futuristic style, holographic elements, sustainable themes.
83
- SMART CITY
84
- β”œβ”€β”€ MOBILITY [Hover Transport ~60px]
85
- β”‚ β”œβ”€β”€ AUTONOMOUS [Self-Driving]
86
- β”‚ └── CONNECTED [Network Grid]
87
- β”œβ”€β”€ ENERGY [Solar Crystal ~55px]
88
- β”‚ β”œβ”€β”€ RENEWABLE [Green Power]
89
- β”‚ └── STORAGE [Battery Hub]
90
- β”œβ”€β”€ LIVING [Eco Building ~50px]
91
- β”‚ β”œβ”€β”€ VERTICAL [Sky Gardens]
92
- β”‚ └── COMMUNITY [People Connect]
93
- └── INFRASTRUCTURE
94
- β”œβ”€β”€ AI GRID [Neural City]
95
- └── ECO SYSTEM [Nature Tech]""",
96
- "width": 1024,
97
- "height": 1024
98
- },
99
- {
100
- "title": "Health Evolution",
101
- "prompt": """A handrawn colorful mind map diagram, medical style, DNA helix patterns, wellness focus.
102
- HEALTH 3.0
103
- β”œβ”€β”€ PREVENTION [Shield DNA ~60px]
104
- β”‚ β”œβ”€β”€ LIFESTYLE [Activity Pulse]
105
- β”‚ └── MONITORING [Health Watch]
106
- β”œβ”€β”€ TREATMENT [Caduceus Tech ~55px]
107
- β”‚ β”œβ”€β”€ PERSONALIZED [DNA Code]
108
- β”‚ └── REGENERATIVE [Cell Renew]
109
- β”œβ”€β”€ ENHANCEMENT [Upgrade Spiral ~50px]
110
- β”‚ β”œοΏ½οΏ½β”€ COGNITIVE [Brain Boost]
111
- β”‚ └── PHYSICAL [Body Optimize]
112
- └── INTEGRATION
113
- β”œβ”€β”€ AI HEALTH [Smart Doctor]
114
- └── COMMUNITY [Global Care]""",
115
- "width": 1024,
116
- "height": 1024
117
- },
118
- {
119
- "title": "Space Exploration",
120
- "prompt": """A handrawn colorful mind map diagram, cosmic style, star field background, planetary elements.
121
- SPACE FRONTIER
122
- β”œβ”€β”€ DISCOVERY [Telescope Array ~60px]
123
- β”‚ β”œβ”€β”€ MAPPING [Star Charts]
124
- β”‚ └── ANALYSIS [Data Stream]
125
- β”œβ”€β”€ TRAVEL [Rocket Launch ~55px]
126
- β”‚ β”œβ”€β”€ PROPULSION [Energy Core]
127
- β”‚ └── NAVIGATION [Space Map]
128
- β”œβ”€β”€ COLONIZATION [Dome City ~50px]
129
- β”‚ β”œβ”€β”€ HABITATS [Life Sphere]
130
- β”‚ └── RESOURCES [Mine Extract]
131
- └── RESEARCH
132
- β”œβ”€β”€ ASTROBIOLOGY [Life Search]
133
- └── PHYSICS [Space Time]""",
134
- "width": 1024,
135
- "height": 1024
136
- },
137
- {
138
- "title": "Ocean Innovation",
139
- "prompt": """A handrawn colorful mind map diagram, marine style, wave patterns, aqua themes.
140
- OCEAN TECH
141
- β”œβ”€β”€ EXPLORATION [Deep Submersible ~60px]
142
- β”‚ β”œβ”€β”€ MAPPING [Sonar Wave]
143
- β”‚ └── RESEARCH [Lab Bubble]
144
- β”œβ”€β”€ CONSERVATION [Marine Life ~55px]
145
- β”‚ β”œβ”€β”€ PROTECTION [Reef Shield]
146
- β”‚ └── RESTORATION [Growth Core]
147
- β”œβ”€β”€ HARVESTING [Sustainable Net ~50px]
148
- β”‚ β”œβ”€β”€ ENERGY [Wave Power]
149
- β”‚ └── RESOURCES [Bio Extract]
150
- └── MONITORING
151
- β”œβ”€β”€ AI SYSTEMS [Smart Sensors]
152
- └── ECOLOGY [Life Web]""",
153
- "width": 1024,
154
- "height": 1024
155
- },
156
- {
157
- "title": "Quantum Computing",
158
- "prompt": """A handrawn colorful mind map diagram, quantum style, wave-particle duality, matrix patterns.
159
- QUANTUM TECH
160
- β”œβ”€β”€ COMPUTATION [Qubit Matrix ~60px]
161
- β”‚ β”œβ”€β”€ PROCESSING [Wave Function]
162
- β”‚ └── ALGORITHMS [Code Quantum]
163
- β”œβ”€β”€ APPLICATIONS [Use Cases ~55px]
164
- β”‚ β”œβ”€β”€ SIMULATION [Model World]
165
- β”‚ └── OPTIMIZATION [Peak Find]
166
- β”œβ”€β”€ INFRASTRUCTURE [Q-Hardware ~50px]
167
- β”‚ β”œβ”€β”€ CONTROL [Pulse Shape]
168
- β”‚ └── COOLING [Zero Point]
169
- └── DEVELOPMENT
170
- β”œβ”€β”€ SOFTWARE [Q-Code Web]
171
- └── INTEGRATION [Classical Bridge]""",
172
- "width": 1024,
173
- "height": 1024
174
- },
175
- {
176
- "title": "Bio Engineering",
177
- "prompt": """A handrawn colorful mind map diagram, biological style, DNA patterns, organic flow.
178
- BIOTECH
179
- β”œβ”€β”€ GENETICS [DNA Helix ~60px]
180
- β”‚ β”œβ”€β”€ EDITING [CRISPR Tool]
181
- β”‚ └── SYNTHESIS [Gene Build]
182
- β”œβ”€β”€ APPLICATIONS [Lab Array ~55px]
183
- β”‚ β”œβ”€β”€ MEDICINE [Heal Cell]
184
- β”‚ └── AGRICULTURE [Grow Plus]
185
- β”œβ”€β”€ PLATFORMS [Bio Factory ~50px]
186
- β”‚ β”œβ”€β”€ SENSORS [Live Detect]
187
- β”‚ └── PROCESSORS [Cell Compute]
188
- └── INTEGRATION
189
- β”œβ”€β”€ AI BIOLOGY [Smart Life]
190
- └── ECOSYSTEM [Nature Net]""",
191
- "width": 1024,
192
- "height": 1024
193
- },
194
- {
195
- "title": "AI Evolution",
196
- "prompt": """A handrawn colorful mind map diagram, neural network style, digital patterns, intelligence flow.
197
- AI FUTURE
198
- β”œβ”€β”€ COGNITION [Brain Network ~60px]
199
- β”‚ β”œβ”€β”€ LEARNING [Growth Path]
200
- β”‚ └── REASONING [Logic Tree]
201
- β”œβ”€β”€ PERCEPTION [Sensor Array ~55px]
202
- β”‚ β”œβ”€β”€ VISION [Eye Matrix]
203
- β”‚ └── LANGUAGE [Word Web]
204
- β”œβ”€β”€ INTERACTION [Connect Hub ~50px]
205
- β”‚ β”œβ”€β”€ HUMAN [Bridge Link]
206
- β”‚ └── MACHINE [Code Path]
207
- └── EVOLUTION
208
- β”œβ”€β”€ CONSCIOUSNESS [Mind Spark]
209
- └── CREATIVITY [Art Core]""",
210
- "width": 1024,
211
- "height": 1024
212
- }
213
- ]
214
 
215
- # Convert examples to Gradio format
216
- GRADIO_EXAMPLES = [
217
- [example["prompt"], example["width"], example["height"]]
218
- for example in EXAMPLES
219
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
 
221
- @spaces.GPU() # 이 λ°μ½”λ ˆμ΄ν„°λ₯Ό λ‹€μ‹œ μΆ”κ°€
222
- def infer(prompt, seed=42, randomize_seed=False, width=1024, height=1024, num_inference_steps=4, progress=gr.Progress(track_tqdm=True)):
223
- if randomize_seed:
224
- seed = random.randint(0, MAX_SEED)
225
- generator = torch.Generator().manual_seed(seed)
226
- image = pipe(
227
- prompt=prompt,
228
- width=width,
229
- height=height,
230
- num_inference_steps=num_inference_steps,
231
- generator=generator,
232
- guidance_scale=0.0
233
- ).images[0]
234
- return image, seed
235
 
236
- # CSS μŠ€νƒ€μΌ μˆ˜μ •
237
- css = """
238
  .container {
239
- display: flex;
240
- flex-direction: row;
241
- height: 100%;
242
  }
243
 
244
- .input-column {
245
- flex: 1;
 
 
 
 
 
246
  padding: 20px;
247
- border-right: 2px solid #eee;
248
- max-width: 800px; /* μ¦κ°€λœ μ΅œλŒ€ λ„ˆλΉ„ */
249
  }
250
 
251
- .examples-column {
252
- flex: 1;
253
- padding: 20px;
254
- overflow-y: auto;
255
- background: #f7f7f7;
 
256
  }
257
 
258
- .title {
259
- text-align: center;
260
- color: #2a2a2a;
261
- padding: 20px;
262
- font-size: 2.5em;
263
- font-weight: bold;
264
- background: linear-gradient(90deg, #f0f0f0 0%, #ffffff 100%);
265
- border-bottom: 3px solid #ddd;
266
- margin-bottom: 30px;
267
  }
268
 
269
- .subtitle {
270
- text-align: center;
271
- color: #666;
272
- margin-bottom: 30px;
273
  }
274
 
275
- .input-box {
276
- background: white;
277
- padding: 20px;
278
- border-radius: 10px;
279
- box-shadow: 0 2px 10px rgba(0,0,0,0.1);
280
- margin-bottom: 20px;
281
- width: 100%; /* 전체 λ„ˆλΉ„ μ‚¬μš© */
282
  }
283
 
284
- /* ν…μŠ€νŠΈ μž…λ ₯ λ°•μŠ€ μŠ€νƒ€μΌ */
285
- .input-box textarea {
286
- width: 100% !important; /* κ°•μ œ λ„ˆλΉ„ 100% */
287
- min-width: 600px !important; /* μ΅œμ†Œ λ„ˆλΉ„ μ„€μ • */
288
- font-size: 14px !important;
289
- line-height: 1.5 !important;
290
- padding: 12px !important;
291
  }
292
 
293
- .example-card {
294
- background: white;
295
- padding: 15px;
296
- margin: 10px 0;
297
- border-radius: 8px;
298
- box-shadow: 0 2px 5px rgba(0,0,0,0.05);
299
  }
300
 
301
- .example-title {
302
- font-weight: bold;
303
- color: #2a2a2a;
304
- margin-bottom: 10px;
 
 
305
  }
306
 
307
- /* λ ˆμ΄μ•„μ›ƒ μ‘°μ • */
308
- .contain {
309
- max-width: 1400px !important; /* 전체 μ»¨ν…Œμ΄λ„ˆ λ„ˆλΉ„ 증가 */
310
- margin: 0 auto !important;
 
 
 
 
 
311
  }
312
 
313
- /* μž…λ ₯ μ˜μ—­ μ‘°μ • */
314
- .input-area {
315
- flex: 2 !important; /* μž…λ ₯ μ˜μ—­ λΉ„μœ¨ 증가 */
316
  }
317
 
318
- /* 예제 μ˜μ—­ μ‘°μ • */
319
- .examples-area {
320
- flex: 1 !important;
 
321
  }
322
- """
323
 
 
 
 
 
 
324
 
325
- # Gradio μΈν„°νŽ˜μ΄μŠ€ μˆ˜μ •
326
- with gr.Blocks(css=css) as demo:
327
- gr.Markdown(
328
- """
329
- <div class="title">FLUX Mindmap Generator</div>
330
- <div class="subtitle">Create beautiful hand-drawn style diagrams using FLUX AI</div>
331
- """)
332
 
 
 
 
 
 
 
 
 
 
 
333
 
 
 
 
 
 
 
 
 
 
 
334
 
335
- with gr.Row(equal_height=True) as main_row:
336
- # μ™Όμͺ½ μž…λ ₯ 컬럼
337
- with gr.Column(elem_id="input-column", scale=2): # scale κ°’ 증가
338
- with gr.Group(elem_classes="input-box"):
339
- prompt = gr.Text(
340
- label="Diagram Prompt",
341
- placeholder="Enter your diagram structure...",
342
- lines=10, # 쀄 수 증가
343
- elem_classes="prompt-input" # CSS 클래슀 μΆ”κ°€
 
 
 
 
 
 
344
  )
345
-
346
- run_button = gr.Button("Generate Diagram", variant="primary")
347
- result = gr.Image(label="Generated Diagram")
348
 
349
- with gr.Accordion("Advanced Settings", open=False):
350
- seed = gr.Slider(
351
- label="Seed",
352
- minimum=0,
353
- maximum=MAX_SEED,
354
- step=1,
355
- value=0,
356
  )
357
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
 
 
 
 
 
 
 
 
 
358
 
359
- with gr.Row():
360
- width = gr.Slider(
361
- label="Width",
362
- minimum=256,
363
- maximum=MAX_IMAGE_SIZE,
364
- step=32,
365
- value=1024,
366
- )
367
- height = gr.Slider(
368
- label="Height",
369
- minimum=256,
370
- maximum=MAX_IMAGE_SIZE,
371
- step=32,
372
- value=1024,
373
- )
374
 
375
- num_inference_steps = gr.Slider(
376
- label="Number of inference steps",
377
- minimum=1,
378
- maximum=50,
379
- step=1,
380
- value=4,
381
- )
382
-
383
- # 였λ₯Έμͺ½ 예제 컬럼
384
- with gr.Column(elem_id="examples-column", scale=1):
385
- gr.Markdown("### Example Diagrams")
386
- for example in EXAMPLES:
387
- with gr.Group(elem_classes="example-card"):
388
- gr.Markdown(f"#### {example['title']}")
389
- gr.Markdown(f"```\n{example['prompt']}\n```")
390
-
391
- def create_example_handler(ex):
392
- def handler():
393
- return {
394
- prompt: ex["prompt"],
395
- width: ex["width"],
396
- height: ex["height"]
397
- }
398
- return handler
399
-
400
- gr.Button("Use This Example", size="sm").click(
401
- fn=create_example_handler(example),
402
- outputs=[prompt, width, height]
403
- )
404
-
405
- gr.on(
406
- triggers=[run_button.click, prompt.submit],
407
- fn=infer,
408
- inputs=[prompt, seed, randomize_seed, width, height, num_inference_steps],
409
- outputs=[result, seed]
410
  )
411
 
412
- # μ•± μ‹€ν–‰
413
- if __name__ == "__main__":
414
- demo.queue()
415
- demo.launch(
416
- server_name="0.0.0.0",
417
- server_port=7860,
418
- share=False,
419
- show_error=True,
420
- debug=True
421
- )
 
1
+ # 2) The actual app
2
+ import os
3
+ from getpass import getpass
4
+ from openai import OpenAI
5
  import gradio as gr
6
+ import requests
7
+ import json
8
+ from datetime import datetime
 
 
 
 
 
9
 
10
+ # β€”β€”β€” Configure your OpenRouter key β€”β€”β€”
11
+ OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
12
+ BSEARCH_API = os.getenv("BSEARCH_API")
 
 
13
 
14
+ # Check if the API key was retrieved
15
+ if not OPENROUTER_API_KEY:
16
+ print("Error: OPENROUTER_API_KEY not found in environment.")
17
+ print("Please set your API key in the environment as 'OPENROUTER_API_KEY'.")
18
+ else:
19
+ client = OpenAI(
20
+ base_url="https://openrouter.ai/api/v1",
21
+ api_key=OPENROUTER_API_KEY,
22
+ )
23
 
24
+ # Brave Search function
25
+ def brave_search(query):
26
+ """Perform a web search using Brave Search API."""
27
+ if not BSEARCH_API:
28
+ return "Error: BSEARCH_API not found in environment. Please set your Brave Search API key."
29
+
30
+ try:
31
+ headers = {
32
+ "Accept": "application/json",
33
+ "X-Subscription-Token": BSEARCH_API
34
+ }
35
+
36
+ # Brave Search API endpoint
37
+ url = "https://api.search.brave.com/res/v1/web/search"
38
+ params = {
39
+ "q": query,
40
+ "count": 5 # Number of results to return
41
+ }
42
+
43
+ response = requests.get(url, headers=headers, params=params)
44
+ response.raise_for_status()
45
+
46
+ data = response.json()
47
+
48
+ # Format the search results
49
+ results = []
50
+ if "web" in data and "results" in data["web"]:
51
+ for idx, result in enumerate(data["web"]["results"][:5], 1):
52
+ title = result.get("title", "No title")
53
+ url = result.get("url", "")
54
+ description = result.get("description", "No description")
55
+ results.append(f"{idx}. **{title}**\n URL: {url}\n {description}\n")
56
+
57
+ if results:
58
+ return "πŸ” **Web Search Results:**\n\n" + "\n".join(results)
59
+ else:
60
+ return "No search results found."
61
+
62
+ except Exception as e:
63
+ return f"Search error: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
+ def openrouter_chat(user_message, history, use_web_search):
66
+ """Send user_message and history to mistralai/devstral-small:free and append to history."""
67
+ history = history or []
68
+
69
+ # If web search is enabled, perform search first
70
+ search_context = ""
71
+ if use_web_search and user_message.strip():
72
+ search_results = brave_search(user_message)
73
+ search_context = f"\n\n{search_results}\n\nBased on the above search results, please answer the following question:\n"
74
+ # Add search results to history as a system message
75
+ history.append(("πŸ” Web Search Query", user_message))
76
+ history.append(("🌐 Search Results", search_results))
77
+
78
+ # Build the messages list from the history and the current user message
79
+ messages_for_api = []
80
+
81
+ # Add system message if web search was used
82
+ if search_context:
83
+ messages_for_api.append({
84
+ "role": "system",
85
+ "content": "You are a helpful assistant. When web search results are provided, incorporate them into your response to give accurate and up-to-date information."
86
+ })
87
+
88
+ for human_message, ai_message in history[:-2] if use_web_search else history: # Exclude search entries from API messages
89
+ if not human_message.startswith("πŸ”") and not human_message.startswith("🌐"):
90
+ messages_for_api.append({"role": "user", "content": human_message})
91
+ if ai_message is not None:
92
+ messages_for_api.append({"role": "assistant", "content": ai_message})
93
+
94
+ # Add the current user message with search context if applicable
95
+ current_message = search_context + user_message if search_context else user_message
96
+ messages_for_api.append({"role": "user", "content": current_message})
97
+
98
+ try:
99
+ # Call the model with the mistralai/Devstral-Small-2505 for full conversation history
100
+ resp = client.chat.completions.create(
101
+ model="mistralai/devstral-small:free",
102
+ messages=messages_for_api,
103
+ # you can tweak max_tokens, temperature, etc. here
104
+ )
105
+ bot_reply = resp.choices[0].message.content
106
+ # Append the user message and bot reply to the history for Gradio display
107
+ history.append((user_message, bot_reply))
108
+ except Exception as e:
109
+ # Handle potential errors and append an error message to the history
110
+ history.append((user_message, f"Error: {e}"))
111
+
112
+ return history, ""
113
 
114
+ # Enhanced CSS with gradient background and visual improvements
115
+ custom_css = """
116
+ /* Gradient background */
117
+ .gradio-container {
118
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #4facfe 75%, #00f2fe 100%);
119
+ min-height: 100vh;
120
+ padding: 20px;
121
+ }
 
 
 
 
 
 
122
 
123
+ /* Main container styling */
 
124
  .container {
125
+ max-width: 1200px;
126
+ margin: 0 auto;
 
127
  }
128
 
129
+ /* Chat container with glassmorphism effect */
130
+ #component-0 {
131
+ background: rgba(255, 255, 255, 0.1);
132
+ backdrop-filter: blur(10px);
133
+ border-radius: 20px;
134
+ border: 1px solid rgba(255, 255, 255, 0.2);
135
+ box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
136
  padding: 20px;
 
 
137
  }
138
 
139
+ /* Chatbot styling */
140
+ .chatbot {
141
+ background: rgba(255, 255, 255, 0.9) !important;
142
+ border-radius: 15px !important;
143
+ border: none !important;
144
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) !important;
145
  }
146
 
147
+ /* Message bubbles */
148
+ .message {
149
+ border-radius: 10px !important;
150
+ padding: 12px 16px !important;
151
+ margin: 8px 0 !important;
 
 
 
 
152
  }
153
 
154
+ .user {
155
+ background-color: #667eea !important;
156
+ color: white !important;
157
+ margin-left: 20% !important;
158
  }
159
 
160
+ .bot {
161
+ background-color: #f0f0f0 !important;
162
+ color: #333 !important;
163
+ margin-right: 20% !important;
 
 
 
164
  }
165
 
166
+ /* Input styling */
167
+ .textbox {
168
+ border-radius: 10px !important;
169
+ border: 2px solid #667eea !important;
170
+ background: rgba(255, 255, 255, 0.95) !important;
171
+ font-size: 16px !important;
 
172
  }
173
 
174
+ .textbox:focus {
175
+ border-color: #764ba2 !important;
176
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.2) !important;
 
 
 
177
  }
178
 
179
+ /* Checkbox styling */
180
+ .checkbox-group {
181
+ background: rgba(255, 255, 255, 0.8) !important;
182
+ border-radius: 10px !important;
183
+ padding: 10px !important;
184
+ margin: 10px 0 !important;
185
  }
186
 
187
+ /* Button styling */
188
+ button {
189
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
190
+ color: white !important;
191
+ border: none !important;
192
+ border-radius: 10px !important;
193
+ padding: 10px 20px !important;
194
+ font-weight: bold !important;
195
+ transition: all 0.3s ease !important;
196
  }
197
 
198
+ button:hover {
199
+ transform: translateY(-2px) !important;
200
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3) !important;
201
  }
202
 
203
+ /* Title styling */
204
+ h1, h2 {
205
+ color: white !important;
206
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3) !important;
207
  }
 
208
 
209
+ /* Markdown styling */
210
+ .markdown-text {
211
+ color: white !important;
212
+ text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3) !important;
213
+ }
214
 
215
+ /* Web search results styling */
216
+ .message:has(.search-results) {
217
+ background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%) !important;
218
+ border-left: 4px solid #ff6b6b !important;
219
+ }
 
 
220
 
221
+ /* Responsive design */
222
+ @media (max-width: 768px) {
223
+ .user {
224
+ margin-left: 10% !important;
225
+ }
226
+ .bot {
227
+ margin-right: 10% !important;
228
+ }
229
+ }
230
+ """
231
 
232
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft()) as demo:
233
+ gr.Markdown(
234
+ """
235
+ <div style="text-align: center; padding: 20px;">
236
+ <h1 style="font-size: 3em; margin-bottom: 10px;">πŸ¦œπŸ”— AI Chat Assistant</h1>
237
+ <h2 style="font-size: 1.5em; opacity: 0.9;">Powered by Devstral-Small with Brave Search Integration</h2>
238
+ </div>
239
+ """,
240
+ elem_id="header"
241
+ )
242
 
243
+ with gr.Row():
244
+ with gr.Column(scale=4):
245
+ chatbot = gr.Chatbot(
246
+ label="πŸ’¬ Chat History",
247
+ height=500,
248
+ elem_classes=["chatbot"],
249
+ bubble_full_width=False
250
+ )
251
+
252
+ with gr.Row():
253
+ msg_in = gr.Textbox(
254
+ placeholder="Type your question here… (Press Enter to send)",
255
+ label="✍️ Your Message",
256
+ scale=4,
257
+ lines=2
258
  )
 
 
 
259
 
260
+ with gr.Row():
261
+ use_web_search = gr.Checkbox(
262
+ label="πŸ” Enable Web Search",
263
+ value=True,
264
+ info="Search the web for current information before answering"
 
 
265
  )
266
+ clear_btn = gr.Button("πŸ—‘οΈ Clear Chat", size="sm")
267
+
268
+ with gr.Column(scale=1):
269
+ gr.Markdown(
270
+ """
271
+ ### πŸ“‹ Features
272
+ - πŸ’¬ Real-time chat with AI
273
+ - πŸ” Web search integration
274
+ - πŸ“œ Conversation history
275
+ - 🎨 Beautiful gradient UI
276
 
277
+ ### πŸ”§ Tips
278
+ - Enable web search for current events
279
+ - Ask follow-up questions
280
+ - Clear chat to start fresh
 
 
 
 
 
 
 
 
 
 
 
281
 
282
+ ### ⚑ Shortcuts
283
+ - Enter: Send message
284
+ - Shift+Enter: New line
285
+ """,
286
+ elem_classes=["markdown-text"]
287
+ )
288
+
289
+ # Event handlers
290
+ msg_in.submit(
291
+ openrouter_chat,
292
+ inputs=[msg_in, chatbot, use_web_search],
293
+ outputs=[chatbot, msg_in]
294
+ )
295
+
296
+ clear_btn.click(lambda: ([], ""), outputs=[chatbot, msg_in])
297
+
298
+ # Add example queries
299
+ gr.Examples(
300
+ examples=[
301
+ ["What's the latest news about AI?", True],
302
+ ["Explain quantum computing in simple terms", False],
303
+ ["What's the weather like today?", True],
304
+ ["Write a Python function to sort a list", False],
305
+ ["What are the current stock market trends?", True]
306
+ ],
307
+ inputs=[msg_in, use_web_search],
308
+ label="πŸ’‘ Example Queries"
 
 
 
 
 
 
 
 
309
  )
310
 
311
+ demo.launch()