Mehedi2 commited on
Commit
a05ba9b
·
verified ·
1 Parent(s): 7dac0f7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +485 -55
app.py CHANGED
@@ -1,70 +1,500 @@
 
 
 
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,
30
- stream=True,
31
- temperature=temperature,
32
- top_p=top_p,
33
- ):
34
- choices = message.choices
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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- chatbot = gr.ChatInterface(
47
- respond,
48
- type="messages",
49
- additional_inputs=[
50
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
51
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
52
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
53
- gr.Slider(
54
- minimum=0.1,
55
- maximum=1.0,
56
- value=0.95,
57
- step=0.05,
58
- label="Top-p (nucleus sampling)",
59
- ),
60
- ],
61
- )
62
-
63
- with gr.Blocks() as demo:
64
- with gr.Sidebar():
65
- gr.LoginButton()
66
- chatbot.render()
 
 
 
67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
 
69
  if __name__ == "__main__":
70
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ import json
4
  import gradio as gr
5
+ from typing import Dict, Any, Optional
6
+
7
+ # Set your OpenRouter API key as environment variable
8
+ OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY") or os.getenv("my_key")
9
+
10
+ class OpenRouterLLM:
11
+ def __init__(self, api_key: str, model: str = "deepseek/deepseek-v3.1-terminus"):
12
+ self.api_key = api_key
13
+ self.model = model
14
+ self.base_url = "https://openrouter.ai/api/v1/chat/completions"
15
+
16
+ def __call__(self, prompt: str, max_tokens: int = 1000, temperature: float = 0.3) -> str:
17
+ """Make API call to OpenRouter with DeepSeek V3.1 Terminus"""
18
+
19
+ if not self.api_key or not self.api_key.startswith('sk-or-v1-'):
20
+ return "Error: Invalid OpenRouter API key. Please configure your API key."
21
+
22
+ headers = {
23
+ "Authorization": f"Bearer {self.api_key}",
24
+ "Content-Type": "application/json",
25
+ "HTTP-Referer": "https://huggingface.co/spaces/Mehedi2/Gaia-Test-Agent",
26
+ "X-Title": "AI Navigation Agent"
27
+ }
28
+
29
+ payload = {
30
+ "model": self.model,
31
+ "messages": [
32
+ {
33
+ "role": "system",
34
+ "content": "You are a helpful AI assistant. Answer questions clearly and accurately."
35
+ },
36
+ {
37
+ "role": "user",
38
+ "content": prompt
39
+ }
40
+ ],
41
+ "temperature": temperature,
42
+ "max_tokens": max_tokens,
43
+ "top_p": 0.9
44
+ }
45
+
46
+ try:
47
+ response = requests.post(
48
+ self.base_url,
49
+ headers=headers,
50
+ json=payload,
51
+ timeout=30
52
+ )
53
+
54
+ if response.status_code == 401:
55
+ return "Error: Invalid API key or unauthorized."
56
+ elif response.status_code == 402:
57
+ return "Error: Insufficient credits in OpenRouter account."
58
+ elif response.status_code == 429:
59
+ return "Error: Rate limit exceeded. Please wait and try again."
60
+ elif response.status_code != 200:
61
+ return f"Error: HTTP {response.status_code} - {response.text[:200]}"
62
+
63
+ result = response.json()
64
+
65
+ if "choices" in result and len(result["choices"]) > 0:
66
+ return result["choices"][0]["message"]["content"].strip()
67
+ else:
68
+ return "Error: No response content received."
69
+
70
+ except requests.exceptions.Timeout:
71
+ return "Error: Request timeout. Please try again."
72
+ except requests.exceptions.RequestException as e:
73
+ return f"Error calling OpenRouter API: {str(e)}"
74
+ except Exception as e:
75
+ return f"Error: {str(e)}"
76
+
77
+ def run_agent(prompt: str) -> str:
78
  """
79
+ Main function for GAIA evaluation
80
+ Takes any text prompt and returns a response
81
  """
82
+ try:
83
+ # Check if API key is available
84
+ if not OPENROUTER_API_KEY:
85
+ return "Error: No API key configured. Please set OPENROUTER_API_KEY environment variable."
86
+
87
+ # Initialize the LLM
88
+ llm = OpenRouterLLM(api_key=OPENROUTER_API_KEY, model="deepseek/deepseek-v3.1-terminus")
89
+
90
+ # Check if this is a navigation-related query
91
+ navigation_keywords = ['route', 'navigation', 'direction', 'coordinate', 'latitude', 'longitude', 'drive', 'travel']
92
+ if any(keyword in prompt.lower() for keyword in navigation_keywords):
93
+ # Try to extract coordinates or provide navigation guidance
94
+ enhanced_prompt = f"""
95
+ You are a navigation assistant. The user asked: "{prompt}"
96
 
97
+ If they provided coordinates, help them with navigation. If not, ask for specific locations or coordinates.
98
+ Provide helpful navigation-related information.
99
+ """
100
+ else:
101
+ # General AI assistant prompt
102
+ enhanced_prompt = f"""
103
+ You are a helpful AI assistant. Please answer the following question accurately and thoroughly:
104
 
105
+ {prompt}
106
 
107
+ Provide a clear, factual response based on your knowledge.
108
+ """
109
+
110
+ # Get response from LLM
111
+ response = llm(enhanced_prompt, max_tokens=1500, temperature=0.3)
112
+ return response
113
+
114
+ except Exception as e:
115
+ return f"Error processing request: {str(e)}"
116
 
117
+ def fetch_route_from_osrm(origin: str, destination: str) -> str:
118
+ """Fetch route from OSRM API"""
119
+
120
+ try:
121
+ # Validate coordinates
122
+ origin_parts = origin.split(',')
123
+ dest_parts = destination.split(',')
124
+
125
+ if len(origin_parts) != 2 or len(dest_parts) != 2:
126
+ return "Error: Coordinates must be in 'longitude,latitude' format"
127
+
128
+ # Parse coordinates
129
+ float(origin_parts[0]), float(origin_parts[1])
130
+ float(dest_parts[0]), float(dest_parts[1])
131
+
132
+ except (ValueError, IndexError):
133
+ return "Error: Invalid coordinate format"
134
+
135
+ url = f"http://router.project-osrm.org/route/v1/driving/{origin};{destination}"
136
+ params = {
137
+ "overview": "false",
138
+ "steps": "true",
139
+ "geometries": "geojson"
140
+ }
141
+
142
+ try:
143
+ response = requests.get(url, params=params, timeout=15)
144
+ response.raise_for_status()
145
+ data = response.json()
146
+
147
+ if not data.get("routes") or len(data["routes"]) == 0:
148
+ return "No route found between the specified locations."
149
+
150
+ route = data["routes"][0]
151
+ total_distance_km = route.get("distance", 0) / 1000
152
+ total_duration_min = route.get("duration", 0) / 60
153
+
154
+ # Process turn-by-turn instructions
155
+ instructions = []
156
+ step_number = 1
157
+
158
+ for leg in route["legs"]:
159
+ for step in leg["steps"]:
160
+ maneuver = step.get("maneuver", {})
161
+ step_type = maneuver.get("type", "continue")
162
+ modifier = maneuver.get("modifier", "")
163
+ road_name = step.get("name", "")
164
+ distance_m = step.get("distance", 0)
165
+
166
+ if distance_m < 10:
167
+ continue
168
+
169
+ instruction = f"{step_number}. "
170
+
171
+ if step_type == "depart":
172
+ direction = "Start your journey"
173
+ if modifier:
174
+ direction += f" heading {modifier}"
175
+ if road_name:
176
+ direction += f" on {road_name}"
177
+
178
+ elif step_type == "arrive":
179
+ instruction += "You have arrived at your destination!"
180
+ instructions.append(instruction)
181
+ break
182
+
183
+ elif step_type == "turn":
184
+ direction = f"Turn {modifier}" if modifier else "Turn"
185
+ if road_name:
186
+ direction += f" onto {road_name}"
187
+
188
+ elif step_type == "merge":
189
+ direction = f"Merge {modifier}" if modifier else "Merge"
190
+ if road_name:
191
+ direction += f" onto {road_name}"
192
+
193
+ elif step_type == "continue":
194
+ direction = "Continue straight"
195
+ if road_name:
196
+ direction += f" on {road_name}"
197
+
198
+ else:
199
+ direction = f"{step_type.replace('_', ' ').title()}"
200
+ if modifier:
201
+ direction += f" {modifier}"
202
+ if road_name:
203
+ direction += f" on {road_name}"
204
+
205
+ if distance_m >= 100:
206
+ if distance_m >= 1000:
207
+ direction += f" for {distance_m/1000:.1f} km"
208
+ else:
209
+ direction += f" for {distance_m:.0f} meters"
210
+
211
+ instruction += direction
212
+ instructions.append(instruction)
213
+ step_number += 1
214
+
215
+ route_summary = f"""ROUTE SUMMARY
216
+ Distance: {total_distance_km:.1f} km
217
+ Estimated Time: {total_duration_min:.0f} minutes
218
+ From: {origin} to {destination}
219
 
220
+ TURN-BY-TURN DIRECTIONS:
221
+ {chr(10).join(instructions)}
 
 
 
 
 
 
 
 
 
222
 
223
+ Total Steps: {len(instructions)}
224
+ """
225
+
226
+ return route_summary.strip()
227
+
228
+ except Exception as e:
229
+ return f"Error fetching route: {str(e)}"
230
 
231
+ def navigate_with_ai(origin_lat, origin_lon, dest_lat, dest_lon, progress=gr.Progress()):
232
+ """Main navigation function for Gradio interface"""
233
+
234
+ progress(0, desc="Starting navigation...")
235
+
236
+ # Validate inputs
237
+ try:
238
+ origin_lat = float(origin_lat)
239
+ origin_lon = float(origin_lon)
240
+ dest_lat = float(dest_lat)
241
+ dest_lon = float(dest_lon)
242
+ except (ValueError, TypeError):
243
+ return "Error: Please enter valid numeric coordinates."
244
+
245
+ # Check coordinate ranges
246
+ if not (-90 <= origin_lat <= 90) or not (-180 <= origin_lon <= 180):
247
+ return "Error: Origin coordinates out of valid range."
248
+ if not (-90 <= dest_lat <= 90) or not (-180 <= dest_lon <= 180):
249
+ return "Error: Destination coordinates out of valid range."
250
+
251
+ # Format coordinates
252
+ origin = f"{origin_lon},{origin_lat}"
253
+ destination = f"{dest_lon},{dest_lat}"
254
+
255
+ progress(0.3, desc="Fetching route data...")
256
+
257
+ # Get route from OSRM
258
+ raw_route = fetch_route_from_osrm(origin, destination)
259
+
260
+ if raw_route.startswith("Error"):
261
+ return raw_route
262
+
263
+ progress(0.7, desc="Generating AI summary...")
264
+
265
+ # Check if API key is available
266
+ if not OPENROUTER_API_KEY:
267
+ return f"""Warning: No API key configured. Showing raw route data:
268
 
269
+ {raw_route}
270
+
271
+ To get AI-enhanced summaries, please configure your OpenRouter API key in the Space settings."""
272
+
273
+ # Generate AI summary
274
+ llm = OpenRouterLLM(api_key=OPENROUTER_API_KEY, model="deepseek/deepseek-v3.1-terminus")
275
+
276
+ prompt = f"""
277
+ Analyze this route information and create a helpful navigation summary:
278
+
279
+ {raw_route}
280
+
281
+ Please provide:
282
+ 1. A brief overview of the journey
283
+ 2. Simplified directions with key landmarks
284
+ 3. Any important notes about the route
285
+ 4. Travel tips if relevant
286
+
287
+ Format your response to be clear and easy to follow.
288
  """
289
+
290
+ progress(0.9, desc="Finalizing response...")
291
+
292
+ ai_summary = llm(prompt, max_tokens=1200, temperature=0.2)
293
+
294
+ progress(1.0, desc="Complete!")
295
+
296
+ return ai_summary
297
+
298
+ # Predefined location examples
299
+ LOCATION_EXAMPLES = {
300
+ "Dhaka, Bangladesh": (23.8103, 90.4125),
301
+ "Chittagong, Bangladesh": (22.3569, 91.7832),
302
+ "London, UK": (51.5074, -0.1278),
303
+ "New York, USA": (40.7128, -74.0060),
304
+ "Paris, France": (48.8566, 2.3522),
305
+ "Tokyo, Japan": (35.6762, 139.6503),
306
+ "Sydney, Australia": (-33.8688, 151.2093)
307
+ }
308
+
309
+ def set_example_location(location_name, is_destination=False):
310
+ """Set example location coordinates"""
311
+ if location_name in LOCATION_EXAMPLES:
312
+ lat, lon = LOCATION_EXAMPLES[location_name]
313
+ return lat, lon
314
+ return None, None
315
 
316
+ # Create Gradio interface
317
+ def create_gradio_app():
318
+ with gr.Blocks(
319
+ title="AI Navigation Agent",
320
+ theme=gr.themes.Soft(),
321
+ css="""
322
+ .main-header {
323
+ text-align: center;
324
+ background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
325
+ color: white;
326
+ padding: 20px;
327
+ border-radius: 10px;
328
+ margin-bottom: 20px;
329
+ }
330
+ """
331
+ ) as app:
332
+
333
+ gr.HTML("""
334
+ <div class="main-header">
335
+ <h1>AI Navigation Agent</h1>
336
+ <p>Get AI-powered route planning with DeepSeek V3.1 Terminus</p>
337
+ </div>
338
+ """)
339
+
340
+ with gr.Row():
341
+ with gr.Column():
342
+ gr.Markdown("### Origin (Starting Point)")
343
+
344
+ with gr.Row():
345
+ origin_lat = gr.Number(
346
+ label="Latitude",
347
+ placeholder="e.g., 23.8103",
348
+ value=23.8103,
349
+ precision=6
350
+ )
351
+ origin_lon = gr.Number(
352
+ label="Longitude",
353
+ placeholder="e.g., 90.4125",
354
+ value=90.4125,
355
+ precision=6
356
+ )
357
+
358
+ origin_examples = gr.Dropdown(
359
+ choices=list(LOCATION_EXAMPLES.keys()),
360
+ label="Or choose a preset location",
361
+ value=None
362
+ )
363
+
364
+ with gr.Column():
365
+ gr.Markdown("### Destination (End Point)")
366
+
367
+ with gr.Row():
368
+ dest_lat = gr.Number(
369
+ label="Latitude",
370
+ placeholder="e.g., 22.3569",
371
+ value=22.3569,
372
+ precision=6
373
+ )
374
+ dest_lon = gr.Number(
375
+ label="Longitude",
376
+ placeholder="e.g., 91.7832",
377
+ value=91.7832,
378
+ precision=6
379
+ )
380
+
381
+ dest_examples = gr.Dropdown(
382
+ choices=list(LOCATION_EXAMPLES.keys()),
383
+ label="Or choose a preset location",
384
+ value=None
385
+ )
386
+
387
+ with gr.Row():
388
+ clear_btn = gr.Button("Clear", variant="secondary")
389
+ navigate_btn = gr.Button("Get Navigation", variant="primary", size="lg")
390
+
391
+ with gr.Row():
392
+ output = gr.Textbox(
393
+ label="Navigation Result",
394
+ lines=20,
395
+ placeholder="Your navigation instructions will appear here...",
396
+ show_copy_button=True
397
+ )
398
+
399
+ # Add a simple chat interface for GAIA testing
400
+ with gr.Row():
401
+ gr.Markdown("### General AI Assistant (for GAIA evaluation)")
402
+
403
+ with gr.Row():
404
+ chat_input = gr.Textbox(
405
+ label="Ask any question",
406
+ placeholder="Type your question here...",
407
+ lines=3
408
+ )
409
+
410
+ with gr.Row():
411
+ chat_btn = gr.Button("Ask AI", variant="primary")
412
+
413
+ with gr.Row():
414
+ chat_output = gr.Textbox(
415
+ label="AI Response",
416
+ lines=10,
417
+ placeholder="AI response will appear here...",
418
+ show_copy_button=True
419
+ )
420
+
421
+ gr.Markdown("""
422
+ ### How to Use:
423
+ 1. **Navigation**: Enter coordinates for route planning
424
+ 2. **General Questions**: Use the chat interface below for any questions
425
+ 3. **GAIA Testing**: The chat interface is used for GAIA evaluation
426
+
427
+ ### Coordinate Format:
428
+ - Latitude: -90 to 90 (North/South)
429
+ - Longitude: -180 to 180 (East/West)
430
+ - Example: Dhaka is at 23.8103, 90.4125
431
+ """)
432
+
433
+ # Event handlers
434
+ def set_origin_example(location):
435
+ if location:
436
+ lat, lon = set_example_location(location)
437
+ return lat, lon
438
+ return gr.update(), gr.update()
439
+
440
+ def set_dest_example(location):
441
+ if location:
442
+ lat, lon = set_example_location(location)
443
+ return lat, lon
444
+ return gr.update(), gr.update()
445
+
446
+ def clear_all():
447
+ return "", "", "", "", None, None, ""
448
+
449
+ # Wire up events
450
+ origin_examples.change(
451
+ fn=set_origin_example,
452
+ inputs=[origin_examples],
453
+ outputs=[origin_lat, origin_lon]
454
+ )
455
+
456
+ dest_examples.change(
457
+ fn=set_dest_example,
458
+ inputs=[dest_examples],
459
+ outputs=[dest_lat, dest_lon]
460
+ )
461
+
462
+ navigate_btn.click(
463
+ fn=navigate_with_ai,
464
+ inputs=[origin_lat, origin_lon, dest_lat, dest_lon],
465
+ outputs=[output],
466
+ show_progress=True
467
+ )
468
+
469
+ clear_btn.click(
470
+ fn=clear_all,
471
+ outputs=[origin_lat, origin_lon, dest_lat, dest_lon, origin_examples, dest_examples, output]
472
+ )
473
+
474
+ # Chat interface for GAIA
475
+ chat_btn.click(
476
+ fn=run_agent,
477
+ inputs=[chat_input],
478
+ outputs=[chat_output]
479
+ )
480
+
481
+ return app
482
 
483
+ # Launch the app
484
  if __name__ == "__main__":
485
+ app = create_gradio_app()
486
+
487
+ # Check if running on Hugging Face Spaces
488
+ if os.getenv("SPACE_ID"):
489
+ # Running on HF Spaces
490
+ app.launch(
491
+ server_name="0.0.0.0",
492
+ server_port=7860,
493
+ show_api=False
494
+ )
495
+ else:
496
+ # Running locally
497
+ app.launch(
498
+ share=True,
499
+ show_api=False
500
+ )