shuv25 commited on
Commit
ca57cb7
·
verified ·
1 Parent(s): afab038

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +308 -159
app.py CHANGED
@@ -1,19 +1,58 @@
1
  import gradio as gr
2
- from deep_agent import agent
3
  import os
4
  import re
 
 
 
5
 
6
  os.makedirs("static", exist_ok=True)
7
 
8
- def process_delivery_query(query):
9
- """Process delivery queries and return text + map"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  if not query.strip():
11
- return "<div style='color:#388e3c; padding:20px; background:#e8f5e9; border-radius:8px;'>Please enter a query</div>", None
12
 
13
  try:
14
- result = agent.invoke({
15
- "messages": [{"role": "user", "content": query}]
16
- })
 
 
 
 
 
 
 
 
 
 
17
 
18
  response_text = ""
19
  if isinstance(result, dict) and "messages" in result:
@@ -23,216 +62,326 @@ def process_delivery_query(query):
23
  break
24
  else:
25
  response_text = str(result)
 
 
 
 
 
 
 
26
 
27
  map_file_path = None
28
  map_url_pattern = r'/view-map/([^\s\)]+\.html)'
29
  map_match = re.search(map_url_pattern, response_text)
30
-
31
  if map_match:
32
  map_filename = map_match.group(1)
33
- map_file_path = f"static/{map_filename}"
 
34
  elif os.path.exists("static"):
35
- map_files = [f for f in os.listdir("static") if f.startswith("route_") and f.endswith(".html")]
 
 
 
 
 
 
 
36
  if map_files:
37
- map_files.sort(key=lambda x: os.path.getmtime(os.path.join("static", x)), reverse=True)
38
- map_file_path = f"static/{map_files[0]}"
 
 
 
 
39
 
40
  response_text = re.sub(map_url_pattern, '', response_text)
41
  response_text = re.sub(r'INTERACTIVE MAP:.*?\n', '', response_text)
42
-
43
- html_response = response_text
44
- html_response = html_response.replace('PRIMARY ROUTE:', '<h3 style="color:#2e7d32; margin-top:25px; border-left:4px solid #2e7d32; padding-left:15px;">PRIMARY ROUTE</h3>')
45
- html_response = html_response.replace('ROUTE COMPARISON:', '<h3 style="color:#388e3c; margin-top:25px; border-left:4px solid #388e3c; padding-left:15px;">ROUTE COMPARISON</h3>')
46
- html_response = html_response.replace('Cost Estimate', '<h3 style="color:#4caf50; margin-top:25px; border-left:4px solid #4caf50; padding-left:15px;">Cost Estimate</h3>')
47
- html_response = html_response.replace('Traffic Analysis', '<h3 style="color:#66bb6a; margin-top:25px; border-left:4px solid #66bb6a; padding-left:15px;">Traffic Analysis</h3>')
48
- html_response = html_response.replace('Route Analysis', '<h3 style="color:#2e7d32; margin-top:25px; border-left:4px solid #2e7d32; padding-left:15px;">Route Analysis</h3>')
49
-
50
- html_response = html_response.replace('\n\n', '<br><br>')
51
- html_response = html_response.replace('\n', '<br>')
52
- html_response = f"<div style='font-family: system-ui; line-height:1.8; color:#2f3e46; padding:20px;'>{html_response}</div>"
53
 
54
- return html_response, map_file_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
 
56
  except Exception as e:
 
57
  error_html = f"""
58
- <div style='padding:25px; background:#e8f5e9; border-left:5px solid #388e3c; border-radius:10px;'>
59
- <h3 style='color:#388e3c; margin:0 0 15px 0;'>Error Occurred</h3>
60
- <p style='margin:0 0 10px 0; color:#33691e;'><strong>Error:</strong> {str(e)}</p>
61
- <div style='margin-top:15px; padding:15px; background:#fff; border-radius:8px;'>
62
- <p style='margin:0; font-size:14px; color:#4e5d4b;'>
63
- <strong>Tips:</strong><br>
64
- - Use full city names: "Mumbai, Maharashtra, India"<br>
65
- - Include country for international routes<br>
66
- - Check spelling of location names
67
- </p>
68
- </div>
69
  </div>
70
  """
71
- return error_html, None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
  with gr.Blocks(
74
- theme=gr.themes.Soft(primary_hue="green", secondary_hue="lime"),
75
- title="SparkDeliver AI",
76
  css="""
77
- body, html {
78
- margin: 0;
79
- padding: 0;
80
- width: 100%;
81
- overflow-x: hidden;
82
- }
83
- .gradio-container {
84
- max-width: 100% !important;
85
- width: 100% !important;
86
- padding: 0 !important;
87
- margin: 0 auto !important;
88
  }
89
- .block {
90
- width: 100% !important;
91
- }
92
- #root > div {
93
- width: 100% !important;
94
  }
95
  """
96
  ) as demo:
97
 
 
 
 
98
  gr.HTML("""
99
- <div style='
100
- text-align: center;
101
- padding: 30px;
102
- background: linear-gradient(135deg, #81c784 0%, #66bb6a 100%);
103
- border-radius: 15px;
104
- color: white;
105
- margin-bottom: 30px;
106
- box-shadow: 0 10px 30px rgba(76, 175, 80, 0.25);
107
- '>
108
- <h1 style='margin:0; font-size:2.8em; font-weight:700;'>
109
- SparkDeliver AI
110
  </h1>
111
- <p style='margin:15px 0 0 0; font-size:1.3em; opacity:0.95; font-weight:300;'>
112
- Real-time Route Planning | Cost Analysis | Traffic Intelligence
113
  </p>
114
- <p style='margin:10px 0 0 0; font-size:1em; opacity:0.85;'>
 
115
  Powered by SparkBrains
116
  </p>
 
117
  </div>
118
  """)
119
-
120
  with gr.Row():
121
- with gr.Column(scale=2):
122
- gr.Markdown("### Enter Your Delivery Query")
123
-
124
  query_input = gr.Textbox(
125
  label="",
126
- placeholder="Example: Plan a delivery route from Mumbai, Maharashtra to Pune, Maharashtra with 500kg cargo",
127
- lines=6,
128
- show_label=False
 
129
  )
130
 
131
  with gr.Row():
132
- submit_btn = gr.Button(
133
- "Optimize Delivery",
134
- variant="primary",
135
- size="lg",
136
- scale=4
137
- )
138
- clear_btn = gr.ClearButton(
139
- [query_input],
140
- value="Clear",
141
- size="lg",
142
- scale=1
143
- )
 
 
 
 
 
 
 
 
144
 
145
  with gr.Row():
146
- with gr.Column(scale=3):
147
- gr.Markdown("### Route Analysis")
148
- output = gr.HTML(label="", show_label=False)
149
-
150
  with gr.Column(scale=2):
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  gr.Markdown("### Interactive Map")
152
  map_output = gr.HTML(
153
  label="",
154
  show_label=False,
155
- value="<div style='padding:40px; text-align:center; color:#388e3c; background:#f1f8e9; border-radius:10px; min-height:400px; display:flex; align-items:center; justify-content:center;'><div><p>Map will appear here after route planning</p></div></div>"
 
 
 
 
 
156
  )
157
 
158
- def process_and_display(query):
159
- """Process query and return both text and map"""
160
- text_result, map_path = process_delivery_query(query)
161
-
162
- if map_path and os.path.exists(map_path):
163
- with open(map_path, 'r', encoding='utf-8') as f:
164
- map_html = f.read()
165
-
166
- map_display = f"""
167
- <div style='width:100%; height:600px; border-radius:10px; overflow:hidden; box-shadow:0 4px 6px rgba(0,0,0,0.1);'>
168
- <iframe srcdoc='{map_html.replace("'", "&apos;")}'
169
- style='width:100%; height:100%; border:none;'>
170
- </iframe>
171
- </div>
172
- """
173
- return text_result, map_display
174
- else:
175
- no_map = """
176
- <div style='padding:40px; text-align:center; color:#388e3c; background:#f1f8e9; border-radius:10px; min-height:400px; display:flex; align-items:center; justify-content:center;'>
177
- <div>
178
- <p>No map available for this query</p>
179
- </div>
180
- </div>
181
- """
182
- return text_result, no_map
183
-
184
  submit_btn.click(
185
- fn=process_and_display,
186
- inputs=query_input,
187
  outputs=[output, map_output]
 
 
 
 
188
  )
189
 
190
- gr.Markdown("### Try These Example Queries")
191
- gr.Examples(
192
- examples=[
193
- "Plan route from Delhi, India to Jaipur, Rajasthan, India",
194
- "Check traffic conditions between Bangalore, Karnataka and Chennai, Tamil Nadu",
195
- "Find optimal route from Mumbai, Maharashtra to Pune, Maharashtra with 500kg cargo",
196
- "What's the best route from Kolkata to Bhubaneswar?",
197
- ],
198
- inputs=query_input,
199
- label=""
200
  )
201
 
202
- gr.HTML("""
203
- <div style='margin-top:30px; padding:25px; background:#f1f8e9; border-radius:15px;'>
204
- <h3 style='margin:0 0 20px 0; color:#2e7d32;'>Features</h3>
205
- <div style='display:grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap:15px;'>
206
- <div style='padding:15px; background:white; border-radius:10px; border-left:4px solid #2e7d32;'>
207
- <strong>Interactive Maps</strong>
208
- <p style='margin:5px 0 0 0; font-size:0.9em; color:#4e5d4b;'>Visual turn-by-turn directions</p>
209
- </div>
210
- <div style='padding:15px; background:white; border-radius:10px; border-left:4px solid #388e3c;'>
211
- <strong>Cost Optimization</strong>
212
- <p style='margin:5px 0 0 0; font-size:0.9em; color:#4e5d4b;'>Real-world pricing estimates</p>
213
- </div>
214
- <div style='padding:15px; background:white; border-radius:10px; border-left:4px solid #66bb6a;'>
215
- <strong>Traffic Analysis</strong>
216
- <p style='margin:5px 0 0 0; font-size:0.9em; color:#4e5d4b;'>Live traffic patterns</p>
217
- </div>
218
- <div style='padding:15px; background:white; border-radius:10px; border-left:4px solid #81c784;'>
219
- <strong>Route Comparison</strong>
220
- <p style='margin:5px 0 0 0; font-size:0.9em; color:#4e5d4b;'>Multiple route options</p>
221
- </div>
222
- </div>
223
- </div>
224
- """)
225
-
226
  gr.Markdown("---")
227
  gr.Markdown(
228
- "<div style='text-align:center; color:#4e5d4b; font-size:0.9em;'>"
229
- "Built with DeepAgents | LangChain | Groq | OpenStreetMap<br>"
230
- "Ready for Multi-Agent Hub Integration"
231
  "</div>"
232
  )
233
 
234
  if __name__ == "__main__":
235
  demo.launch(
236
  server_name="0.0.0.0",
237
- server_port=7860,
238
- )
 
 
1
  import gradio as gr
2
+ from deep_agent import invoke_agent_for_user
3
  import os
4
  import re
5
+ import traceback
6
+ import uuid
7
+ import hashlib
8
 
9
  os.makedirs("static", exist_ok=True)
10
 
11
+ def get_user_id(request: gr.Request) -> str:
12
+ """
13
+ Generate a unique user ID based on session or IP.
14
+
15
+ In production, replace this with proper authentication:
16
+ - OAuth tokens
17
+ - Session cookies
18
+ - Database user IDs
19
+ """
20
+ if request:
21
+ session_hash = request.session_hash if hasattr(request, 'session_hash') else None
22
+ if session_hash:
23
+ return f"user_{session_hash}"
24
+
25
+ # Fallback to IP-based ID (not ideal for production)
26
+ client_ip = request.client.host if hasattr(request, 'client') else "unknown"
27
+ return f"user_{hashlib.md5(client_ip.encode()).hexdigest()[:8]}"
28
+
29
+ # Fallback for testing
30
+ return f"user_{uuid.uuid4().hex[:8]}"
31
+
32
+
33
+ def process_delivery_query(query, user_session_id, request: gr.Request):
34
+ """
35
+ Process delivery queries with multi-user support.
36
+
37
+ Each user has isolated memory and cannot access other users' data.
38
+ """
39
  if not query.strip():
40
+ return "<div style='color:#d32f2f; padding:20px; background:#ffebee; border-radius:8px; border-left:4px solid #d32f2f;'>Please enter a query</div>", None, user_session_id
41
 
42
  try:
43
+
44
+ user_id = get_user_id(request)
45
+
46
+
47
+ if not user_session_id:
48
+ user_session_id = str(uuid.uuid4())
49
+
50
+
51
+ result = invoke_agent_for_user(
52
+ user_id=user_id,
53
+ message=query,
54
+ thread_id=user_session_id
55
+ )
56
 
57
  response_text = ""
58
  if isinstance(result, dict) and "messages" in result:
 
62
  break
63
  else:
64
  response_text = str(result)
65
+
66
+ print("="*60)
67
+ print(f"USER: {user_id} | THREAD: {user_session_id}")
68
+ print("AGENT RESPONSE:")
69
+ print(response_text)
70
+ print("="*60)
71
+
72
 
73
  map_file_path = None
74
  map_url_pattern = r'/view-map/([^\s\)]+\.html)'
75
  map_match = re.search(map_url_pattern, response_text)
76
+
77
  if map_match:
78
  map_filename = map_match.group(1)
79
+ map_file_path = os.path.join("static", map_filename)
80
+
81
  elif os.path.exists("static"):
82
+ map_files = [
83
+ f for f in os.listdir("static")
84
+ if (
85
+ f.startswith("route_")
86
+ or f.startswith("traffic_")
87
+ or f.startswith("weather_")
88
+ ) and f.endswith(".html")
89
+ ]
90
  if map_files:
91
+ map_files.sort(
92
+ key=lambda x: os.path.getmtime(os.path.join("static", x)),
93
+ reverse=True,
94
+ )
95
+ map_file_path = os.path.join("static", map_files[0])
96
+
97
 
98
  response_text = re.sub(map_url_pattern, '', response_text)
99
  response_text = re.sub(r'INTERACTIVE MAP:.*?\n', '', response_text)
 
 
 
 
 
 
 
 
 
 
 
100
 
101
+ html_response = format_response(response_text)
102
+
103
+ map_display = None
104
+ if map_file_path and os.path.exists(map_file_path):
105
+ with open(map_file_path, 'r', encoding='utf-8') as f:
106
+ map_html = f.read()
107
+
108
+ map_display = f"""
109
+ <div style='width:100%; height:650px; border-radius:12px; overflow:hidden;
110
+ box-shadow:0 4px 12px rgba(0,0,0,0.15); border:1px solid #e0e0e0;'>
111
+ <iframe srcdoc='{map_html.replace("'", "&apos;")}'
112
+ style='width:100%; height:100%; border:none;'>
113
+ </iframe>
114
+ </div>
115
+ """
116
+
117
+ return html_response, map_display, user_session_id
118
 
119
+
120
  except Exception as e:
121
+ traceback.print_exc()
122
  error_html = f"""
123
+ <div style='padding:25px; background:#ffebee; border-left:5px solid #ef5350;
124
+ border-radius:10px; box-shadow:0 2px 8px rgba(0,0,0,0.1);'>
125
+ <h3 style='color:#c62828; margin:0 0 15px 0; font-weight:600;'>Error Occurred</h3>
126
+ <p style='margin:0; color:#b71c1c; line-height:1.6;'><strong>Details:</strong> {str(e)}</p>
 
 
 
 
 
 
 
127
  </div>
128
  """
129
+ return error_html, None, user_session_id
130
+
131
+
132
+ def format_response(text):
133
+ """Format response text into structured HTML sections"""
134
+
135
+ if not text or len(text.strip()) < 10:
136
+ return """<div style='padding:40px; text-align:center; color:#757575; background:#fafafa;
137
+ border-radius:10px; min-height:300px; display:flex; align-items:center;
138
+ justify-content:center;'>
139
+ <div><p style='font-size:1.1em;'>No response received</p></div></div>"""
140
+
141
+
142
+ sections = {
143
+ 'route': '',
144
+ 'weather': '',
145
+ 'traffic': '',
146
+ 'cost': '',
147
+ 'other': ''
148
+ }
149
+
150
+ current_section = 'other'
151
+ lines = text.split('\n')
152
+
153
+ for line in lines:
154
+ line_upper = line.upper()
155
+ if 'ROUTE' in line_upper and ('SUMMARY' in line_upper or 'ANALYSIS' in line_upper):
156
+ current_section = 'route'
157
+ continue
158
+ elif 'WEATHER' in line_upper and ('CONDITION' in line_upper or 'ANALYSIS' in line_upper):
159
+ current_section = 'weather'
160
+ continue
161
+ elif 'TRAFFIC' in line_upper and 'ANALYSIS' in line_upper:
162
+ current_section = 'traffic'
163
+ continue
164
+ elif 'COST' in line_upper and ('ESTIMATE' in line_upper or 'BREAKDOWN' in line_upper):
165
+ current_section = 'cost'
166
+ continue
167
+
168
+ sections[current_section] += line + '\n'
169
+
170
+ html = "<div style='font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;'>"
171
+
172
+ cards_created = 0
173
+
174
+ if sections['route'].strip():
175
+ html += create_card("Route Information", sections['route'], "#78C841", "route")
176
+ cards_created += 1
177
+
178
+ if sections['traffic'].strip():
179
+ html += create_card("Traffic Analysis", sections['traffic'], "#f57c00", "traffic")
180
+ cards_created += 1
181
+
182
+ if sections['weather'].strip():
183
+ html += create_card("Weather Conditions", sections['weather'], "#6B8E23", "weather")
184
+ cards_created += 1
185
+
186
+ if sections['cost'].strip():
187
+ html += create_card("Cost Estimate", sections['cost'], "#7b1fa2", "cost")
188
+ cards_created += 1
189
+
190
+ if cards_created == 0:
191
+ html += f"""<div style='padding:20px; background:#f5f5f5; border-radius:10px; line-height:1.8;'>
192
+ {text.replace('\n', '<br>')}</div>"""
193
+
194
+ html += "</div>"
195
+ return html
196
+
197
+
198
+ def create_card(title, content, color, card_type):
199
+ """Create a styled card for each section"""
200
+
201
+ formatted_content = content.strip()
202
+
203
+ if not formatted_content or len(formatted_content) < 3:
204
+ return ""
205
+
206
+ formatted_content = formatted_content.replace('\n', '<br>')
207
+
208
+ formatted_content = re.sub(
209
+ r'(Distance:|Duration:|ETA:|Base Duration:|Adjusted ETA:|Temperature:|Traffic:|Cost:|Vehicle:|Origin:|Destination:|Current Traffic:|Traffic Factor:|Expected Delay:|Advice:|Recommended Vehicle:|Total Cost:|Weather Alerts?:|Condition:)',
210
+ r'<strong>\1</strong>',
211
+ formatted_content
212
+ )
213
+
214
+ if 'WARNING' in formatted_content.upper() or 'ALERT' in formatted_content.upper() or 'Heavy' in formatted_content:
215
+ border_color = '#ef5350'
216
+ bg_color = '#ffebee'
217
+ else:
218
+ border_color = color
219
+ bg_color = f'{color}15'
220
+
221
+ card_html = f"""
222
+ <div style='margin-bottom:20px; border-radius:10px; overflow:hidden;
223
+ box-shadow:0 2px 8px rgba(0,0,0,0.1); border-left:4px solid {border_color};'>
224
+ <div style='background:{color}; color:white; padding:15px; font-weight:600; font-size:1.1em;'>
225
+ {title}
226
+ </div>
227
+ <div style='background:{bg_color}; padding:20px; line-height:1.8; color:#2e2e2e;'>
228
+ {formatted_content}
229
+ </div>
230
+ </div>
231
+ """
232
+ return card_html
233
+
234
+
235
+ def clear_all():
236
+ """Clear all outputs"""
237
+ return (
238
+ "",
239
+ "<div style='padding:40px; text-align:center; color:#757575; background:#fafafa; border-radius:10px; min-height:300px; display:flex; align-items:center; justify-content:center;'><div><p style='font-size:1.1em;'>Your route details will appear here</p><p style='font-size:0.9em; margin-top:10px; color:#9e9e9e;'>Enter a query and click Send to get started</p></div></div>",
240
+ "<div style='padding:40px; text-align:center; color:#757575; background:#fafafa; border-radius:10px; min-height:600px; display:flex; align-items:center; justify-content:center;'><div><p style='font-size:1.1em;'>Interactive map will appear here</p><p style='font-size:0.9em; margin-top:10px; color:#9e9e9e;'>Plan a route to see the map</p></div></div>",
241
+ None
242
+ )
243
+
244
 
245
  with gr.Blocks(
246
+ theme=gr.themes.Soft(primary_hue="green", secondary_hue="emerald"),
247
+ title="SparkDelivery - Intelligent Route Planning",
248
  css="""
249
+ .gradio-container { max-width: 100% !important; }
250
+ .input-box textarea { font-size: 1.05em !important; }
251
+ button.primary {
252
+ background: #78C841 !important;
253
+ border-color: #78C841 !important;
254
+ color: white !important;
 
 
 
 
 
255
  }
256
+ button.primary:hover {
257
+ background: #5d8a47 !important;
258
+ border-color: #5d8a47 !important;
 
 
259
  }
260
  """
261
  ) as demo:
262
 
263
+
264
+ user_session_state = gr.State(value=None)
265
+
266
  gr.HTML("""
267
+ <div style='text-align:center; padding:40px 30px;
268
+ background:linear-gradient(135deg, #78C841 0%, #5d8a47 100%);
269
+ border-radius:15px; color:white; margin-bottom:30px;
270
+ box-shadow:0 10px 30px rgba(76,118,59,0.3);'>
271
+ <h1 style='margin:0; font-size:3em; font-weight:700; letter-spacing:-1px;'>
272
+ 🚚 SparkDelivery
 
 
 
 
 
273
  </h1>
274
+ <p style='margin:20px 0 0 0; font-size:1.2em; opacity:0.95; font-weight:300;'>
275
+ Intelligent Route Planning with Real-Time Weather and Traffic Analysis
276
  </p>
277
+ <div style='margin-top:20px; font-size:0.95em; opacity:0.85;'>
278
+ <p style='margin:20px 0 0 0; font-size:1.2em; opacity:0.95; font-weight:300;'>
279
  Powered by SparkBrains
280
  </p>
281
+ </div>
282
  </div>
283
  """)
284
+
285
  with gr.Row():
286
+ with gr.Column(scale=1):
287
+ gr.Markdown("### Query Input")
 
288
  query_input = gr.Textbox(
289
  label="",
290
+ placeholder="Examples:\n• Plan route from Mumbai to Pune\n• Route from Delhi to Jaipur with 500kg package\n• What was my last route?\n• Save preference: I prefer morning deliveries",
291
+ lines=5,
292
+ show_label=False,
293
+ elem_classes=["input-box"]
294
  )
295
 
296
  with gr.Row():
297
+ submit_btn = gr.Button("Send", variant="primary", size="lg", scale=3, elem_classes=["primary"])
298
+ clear_btn = gr.Button("Clear", size="lg", scale=1)
299
+
300
+ gr.Markdown("### Quick Examples")
301
+ gr.Examples(
302
+ examples=[
303
+ "Plan route from Delhi to Chandigarh",
304
+ "Route from Mumbai to Pune with 200kg cargo",
305
+ "What was my last route?",
306
+ "Save preference: I prefer morning deliveries",
307
+ "Traffic conditions Bhopal to Jaipur",
308
+ "Weather conditions Mumbai to Pune",
309
+ ],
310
+ inputs=query_input,
311
+ label=""
312
+ )
313
+
314
+ gr.Markdown("---")
315
+
316
+ gr.Markdown("## Results")
317
 
318
  with gr.Row():
 
 
 
 
319
  with gr.Column(scale=2):
320
+ gr.Markdown("### Route Details")
321
+ output = gr.HTML(
322
+ label="",
323
+ show_label=False,
324
+ value="""<div style='padding:40px; text-align:center; color:#757575; background:#fafafa;
325
+ border-radius:10px; min-height:300px; display:flex; align-items:center;
326
+ justify-content:center;'>
327
+ <div><p style='font-size:1.1em;'>Your route details will appear here</p>
328
+ <p style='font-size:0.9em; margin-top:10px; color:#9e9e9e;'>
329
+ Enter a query and click Send to get started</p></div></div>"""
330
+ )
331
+
332
+ with gr.Column(scale=3):
333
  gr.Markdown("### Interactive Map")
334
  map_output = gr.HTML(
335
  label="",
336
  show_label=False,
337
+ value="""<div style='padding:40px; text-align:center; color:#757575; background:#fafafa;
338
+ border-radius:10px; min-height:600px; display:flex; align-items:center;
339
+ justify-content:center;'>
340
+ <div><p style='font-size:1.1em;'>Interactive map will appear here</p>
341
+ <p style='font-size:0.9em; margin-top:10px; color:#9e9e9e;'>
342
+ Plan a route to see the map</p></div></div>"""
343
  )
344
 
345
+ def reset_before_new_query():
346
+ return (
347
+ "<div style='padding:40px; text-align:center; color:#757575; background:#fafafa; border-radius:10px; min-height:300px;'>Processing new request...</div>",
348
+ "<div style='padding:40px; text-align:center; color:#757575; background:#fafafa; border-radius:10px; min-height:600px;'>Loading new map...</div>",
349
+ )
350
+
351
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
352
  submit_btn.click(
353
+ fn=reset_before_new_query,
354
+ inputs=None,
355
  outputs=[output, map_output]
356
+ ).then(
357
+ fn=process_delivery_query,
358
+ inputs=[query_input, user_session_state],
359
+ outputs=[output, map_output, user_session_state],
360
  )
361
 
362
+ query_input.submit(
363
+ fn=process_delivery_query,
364
+ inputs=[query_input, user_session_state],
365
+ outputs=[output, map_output, user_session_state]
 
 
 
 
 
 
366
  )
367
 
368
+ clear_btn.click(
369
+ fn=clear_all,
370
+ inputs=None,
371
+ outputs=[query_input, output, map_output, user_session_state]
372
+ )
373
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
  gr.Markdown("---")
375
  gr.Markdown(
376
+ "<div style='text-align:center; color:#666; font-size:0.9em; padding:20px;'>"
377
+ "Powered by DeepAgents | LangChain | Gemini | OpenStreetMap | OpenWeatherMap | TomTom<br>"
378
+ "<span style='color:#78C841; font-size:0.85em; font-weight:600;'>Real-time routing with multi-user memory isolation</span>"
379
  "</div>"
380
  )
381
 
382
  if __name__ == "__main__":
383
  demo.launch(
384
  server_name="0.0.0.0",
385
+ server_port=7861,
386
+ share=False
387
+ )