wangzerui commited on
Commit
69ca011
Β·
1 Parent(s): d8fafa8
Files changed (2) hide show
  1. __pycache__/app.cpython-311.pyc +0 -0
  2. app.py +100 -232
__pycache__/app.cpython-311.pyc CHANGED
Binary files a/__pycache__/app.cpython-311.pyc and b/__pycache__/app.cpython-311.pyc differ
 
app.py CHANGED
@@ -1,280 +1,148 @@
1
  #!/usr/bin/env python3
2
  """
3
  Hugging Face Spaces deployment for Residential Architecture Assistant
4
- Multi-Agent LangGraph System for Architecture Consultation
5
  """
6
 
7
  import os
8
  import gradio as gr
9
- import json
10
  import traceback
11
- from typing import List, Tuple, Dict, Any
12
- from datetime import datetime
13
 
14
- # Import the core system
15
- from graph import ArchitectureAssistant
16
-
17
- class HuggingFaceArchitectureApp:
18
- """Hugging Face Spaces compatible wrapper for the Architecture Assistant"""
19
-
20
- def __init__(self):
21
- self.assistant = None
22
- self.conversation_history = []
23
-
24
- def initialize_assistant(self, api_key: str, user_id: str = None) -> Tuple[str, bool]:
25
- """Initialize the assistant with API key"""
26
- try:
27
- if not api_key or api_key.strip() == "":
28
- return "❌ Please provide your OpenAI API key to get started.", False
29
-
30
- # Initialize the assistant
31
- self.assistant = ArchitectureAssistant(
32
- openai_api_key=api_key.strip(),
33
- user_id=user_id or f"hf_user_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
34
- )
35
-
36
- return "βœ… Architecture Assistant initialized! You can now start your consultation.", True
37
-
38
- except Exception as e:
39
- error_msg = f"❌ Error initializing assistant: {str(e)}"
40
- print(f"Initialization error: {traceback.format_exc()}")
41
- return error_msg, False
42
 
43
- def chat_with_assistant(self, message: str, history: List[List[str]], api_key: str) -> Tuple[List[List[str]], str]:
44
- """Process chat message and return updated history"""
45
  try:
46
- # Check if assistant is initialized
47
- if not self.assistant or not api_key:
48
- error_response = "❌ Please provide your OpenAI API key first."
49
- history.append([message, error_response])
 
 
50
  return history, ""
51
 
52
- # Get response from assistant
53
- response = self.assistant.chat(message)
54
-
55
- # Add to history
56
- history.append([message, response])
57
-
58
- return history, ""
59
-
60
- except Exception as e:
61
- error_response = f"❌ Error: {str(e)}\n\nPlease check your API key and try again."
62
- print(f"Chat error: {traceback.format_exc()}")
63
- history.append([message, error_response])
64
- return history, ""
65
-
66
- def get_conversation_summary(self, api_key: str) -> str:
67
- """Get current conversation summary"""
68
- try:
69
- if not self.assistant or not api_key:
70
- return "❌ Assistant not initialized. Please provide your API key first."
71
-
72
- summary = self.assistant.get_conversation_summary()
73
-
74
- # Format summary nicely
75
- formatted_summary = f"""πŸ“‹ **CONVERSATION SUMMARY**
76
 
77
- πŸ‘€ **User Requirements:**
78
- β€’ Budget: ${summary['user_requirements'].get('budget', 0):,} CAD
79
- β€’ Location: {summary['user_requirements'].get('location', 'Not specified')}
80
- β€’ Family Size: {summary['user_requirements'].get('family_size', 'Not specified')}
81
- β€’ Preferences: {', '.join(summary['user_requirements'].get('lifestyle_preferences', []) or ['None specified'])}
82
 
83
- 🏠 **Floorplan Requirements:**
84
- β€’ Total Square Footage: {summary['floorplan_requirements'].get('total_sqft', 'Not specified')} sq ft
85
- β€’ Number of Floors: {summary['floorplan_requirements'].get('num_floors', 'Not specified')}
86
- β€’ Lot Dimensions: {summary['floorplan_requirements'].get('lot_dimensions', 'Not specified')}
87
- β€’ Rooms: {len(summary['floorplan_requirements'].get('rooms', []))} room types specified
88
 
89
- πŸ“Š **Progress:**
90
- β€’ Total Messages: {summary['total_messages']}
91
- β€’ Current Topic: {summary['current_topic'] or 'General consultation'}
92
- """
93
-
94
- return formatted_summary
95
 
96
  except Exception as e:
97
- return f"❌ Error getting summary: {str(e)}"
98
-
99
- def reset_conversation(self, api_key: str) -> Tuple[List, str, str]:
100
- """Reset the conversation"""
101
- try:
102
- if self.assistant and api_key:
103
- self.assistant.reset_conversation()
104
- return [], "", "βœ… Conversation reset. You can start a new consultation."
105
- else:
106
- return [], "", "❌ Please initialize with your API key first."
107
- except Exception as e:
108
- return [], "", f"❌ Error resetting: {str(e)}"
109
-
110
- # Create app instance
111
- app = HuggingFaceArchitectureApp()
112
-
113
- # Create Gradio interface
114
- def create_gradio_interface():
115
- """Create the Gradio interface for Hugging Face Spaces"""
116
 
117
- with gr.Blocks(
118
- title="🏠 Residential Architecture Assistant",
119
- theme=gr.themes.Soft(),
120
- css="""
121
- .container { max-width: 1200px; margin: auto; }
122
- .header { text-align: center; padding: 20px; }
123
- .chat-container { height: 500px; }
124
- .summary-box { background-color: #f8f9fa; padding: 15px; border-radius: 10px; }
125
- """
126
- ) as demo:
127
 
128
- # Header
129
  gr.HTML("""
130
- <div class="header">
131
  <h1>🏠 Residential Architecture Assistant</h1>
132
- <p><em>Multi-Agent LangGraph System for Professional Architecture Consultation</em></p>
133
- <p><strong>✨ 7 AI Specialists | πŸ“ Professional Floorplans | πŸ’° Montreal Market Analysis | πŸ“‹ Building Codes</strong></p>
134
  </div>
135
  """)
136
 
137
- # API Key input (persistent across the session)
138
- with gr.Row():
139
- api_key_input = gr.Textbox(
140
- label="πŸ”‘ OpenAI API Key",
141
- placeholder="Enter your OpenAI API key (sk-...)",
142
- type="password",
143
- info="Your API key is used securely and not stored. Required for AI agent functionality."
144
- )
145
-
146
- with gr.Row():
147
- init_btn = gr.Button("πŸš€ Initialize Assistant", variant="primary", size="sm")
148
- reset_btn = gr.Button("πŸ”„ Reset Conversation", variant="secondary", size="sm")
149
 
150
- init_status = gr.HTML("")
 
 
 
 
 
 
 
 
 
 
151
 
152
- # Main chat interface
153
  with gr.Row():
154
- with gr.Column(scale=2):
155
- chatbot = gr.Chatbot(
156
- label="πŸ’¬ Architecture Consultation",
157
- height=500,
158
- show_label=True
159
- )
160
-
161
- with gr.Row():
162
- msg_input = gr.Textbox(
163
- label="Your Message",
164
- placeholder="Ask about home design, budgets, floorplans, building codes...",
165
- lines=2,
166
- scale=4
167
- )
168
- send_btn = gr.Button("πŸ“€ Send", variant="primary", scale=1)
169
-
170
- with gr.Column(scale=1):
171
- gr.HTML("<h3>πŸ“Š Project Status</h3>")
172
- summary_display = gr.HTML(
173
- value="<div class='summary-box'>Initialize the assistant to see your project summary.</div>",
174
- label="Conversation Summary"
175
- )
176
-
177
- summary_btn = gr.Button("πŸ”„ Update Summary", variant="secondary", size="sm")
178
 
179
- # Usage instructions
180
- with gr.Accordion("πŸ“– How to Use", open=False):
181
- gr.HTML("""
182
- <div style="padding: 15px;">
183
- <h4>πŸš€ Getting Started:</h4>
184
- <ol>
185
- <li>Enter your OpenAI API key above</li>
186
- <li>Click "Initialize Assistant"</li>
187
- <li>Start your consultation with questions like:</li>
188
- </ol>
189
-
190
- <h4>πŸ’‘ Example Questions:</h4>
191
- <ul>
192
- <li>"I want to design a home but don't know where to start"</li>
193
- <li>"I have a $800,000 budget for Montreal - is that realistic?"</li>
194
- <li>"We're a family of 4, what size house do we need?"</li>
195
- <li>"Can you generate a floorplan for a 2500 sq ft house?"</li>
196
- <li>"What building permits do I need in Montreal?"</li>
197
- </ul>
198
-
199
- <h4>πŸ€– Our AI Specialists:</h4>
200
- <ul>
201
- <li><strong>RouterAgent:</strong> Intelligent conversation routing</li>
202
- <li><strong>GeneralDesignAgent:</strong> Architecture principles & design guidance</li>
203
- <li><strong>BudgetAnalysisAgent:</strong> Montreal market cost analysis</li>
204
- <li><strong>FloorplanAgent:</strong> Spatial planning & requirements</li>
205
- <li><strong>FloorplanGeneratorAgent:</strong> Detailed architectural specifications</li>
206
- <li><strong>DetailedBudgetAgent:</strong> Comprehensive cost breakdowns</li>
207
- <li><strong>RegulationAgent:</strong> Montreal building codes & permits</li>
208
- </ul>
209
- </div>
210
- """)
211
 
212
  # Event handlers
213
- def handle_init(api_key):
214
- status_msg, success = app.initialize_assistant(api_key)
215
- if success:
216
- return gr.HTML(f"<div style='color: green; padding: 10px;'>{status_msg}</div>")
217
- else:
218
- return gr.HTML(f"<div style='color: red; padding: 10px;'>{status_msg}</div>")
219
-
220
- def handle_chat(message, history, api_key):
221
- return app.chat_with_assistant(message, history, api_key)
222
-
223
- def handle_summary(api_key):
224
- summary = app.get_conversation_summary(api_key)
225
- return f"<div class='summary-box'>{summary}</div>"
226
-
227
- def handle_reset(api_key):
228
- history, msg, status = app.reset_conversation(api_key)
229
- return history, msg, gr.HTML(f"<div style='color: green; padding: 10px;'>{status}</div>")
230
-
231
- # Wire up events
232
- init_btn.click(
233
- handle_init,
234
- inputs=[api_key_input],
235
- outputs=[init_status]
236
- )
237
-
238
- msg_input.submit(
239
- handle_chat,
240
- inputs=[msg_input, chatbot, api_key_input],
241
- outputs=[chatbot, msg_input]
242
  )
243
 
244
  send_btn.click(
245
- handle_chat,
246
- inputs=[msg_input, chatbot, api_key_input],
247
- outputs=[chatbot, msg_input]
248
  )
249
 
250
- summary_btn.click(
251
- handle_summary,
252
- inputs=[api_key_input],
253
- outputs=[summary_display]
254
- )
255
-
256
- reset_btn.click(
257
- handle_reset,
258
- inputs=[api_key_input],
259
- outputs=[chatbot, msg_input, init_status]
260
  )
261
 
262
  # Footer
263
  gr.HTML("""
264
  <div style="text-align: center; padding: 20px; margin-top: 30px; border-top: 1px solid #ddd;">
265
- <p><strong>🏠 Residential Architecture Assistant v3.0</strong></p>
266
- <p>Built with <a href="https://langchain.ai/langgraph">LangGraph</a> β€’
267
- Powered by <a href="https://openai.com">OpenAI</a> β€’
268
- Interface by <a href="https://gradio.app">Gradio</a></p>
269
- <p><em>Professional architecture consultation from concept to construction</em></p>
270
  </div>
271
  """)
272
 
273
  return demo
274
 
275
- # Create and launch the interface
276
  if __name__ == "__main__":
277
- demo = create_gradio_interface()
278
-
279
- # Launch configuration for Hugging Face Spaces
280
  demo.launch()
 
1
  #!/usr/bin/env python3
2
  """
3
  Hugging Face Spaces deployment for Residential Architecture Assistant
4
+ Simplified version to avoid schema issues
5
  """
6
 
7
  import os
8
  import gradio as gr
 
9
  import traceback
10
+ from typing import List, Tuple
 
11
 
12
+ # Create a minimal interface without complex imports to avoid schema issues
13
+ def create_simple_interface():
14
+ """Create a simple Gradio interface that works reliably in HF Spaces"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
+ def handle_message(message: str, history: List[List[str]], api_key: str) -> Tuple[List[List[str]], str]:
17
+ """Simple message handler"""
18
  try:
19
+ if not api_key or not api_key.strip():
20
+ error_msg = "❌ Please provide your OpenAI API key to start using the Architecture Assistant."
21
+ history.append([message, error_msg])
22
+ return history, ""
23
+
24
+ if not message.strip():
25
  return history, ""
26
 
27
+ # Try to import and use the actual system
28
+ try:
29
+ from graph import ArchitectureAssistant
30
+
31
+ # Create assistant instance
32
+ assistant = ArchitectureAssistant(
33
+ openai_api_key=api_key.strip(),
34
+ user_id=f"hf_user_{len(history)}"
35
+ )
36
+
37
+ # Get response
38
+ response = assistant.chat(message)
39
+ history.append([message, response])
40
+
41
+ except Exception as e:
42
+ # Fallback error handling
43
+ error_msg = f"""❌ **System Error**: {str(e)}
 
 
 
 
 
 
 
44
 
45
+ **Possible Solutions:**
46
+ 1. **Check your OpenAI API key** - Make sure it's valid and has sufficient credits
47
+ 2. **Try again** - Sometimes there are temporary connection issues
48
+ 3. **Simpler questions** - Start with basic architecture questions
 
49
 
50
+ **This is a multi-agent LangGraph system** that provides:
51
+ - πŸ›οΈ **Architecture design guidance**
52
+ - πŸ’° **Montreal market cost analysis**
53
+ - πŸ“ **Professional floorplan generation**
54
+ - πŸ“‹ **Building codes & permit requirements**
55
 
56
+ Please try your question again, or contact support if the issue persists."""
57
+
58
+ history.append([message, error_msg])
59
+
60
+ return history, ""
 
61
 
62
  except Exception as e:
63
+ # Final fallback
64
+ error_msg = f"❌ Unexpected error: {str(e)}"
65
+ history.append([message, error_msg])
66
+ return history, ""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
+ # Create interface with minimal components
69
+ with gr.Blocks(title="🏠 Architecture Assistant") as demo:
 
 
 
 
 
 
 
 
70
 
 
71
  gr.HTML("""
72
+ <div style="text-align: center; padding: 20px;">
73
  <h1>🏠 Residential Architecture Assistant</h1>
74
+ <p><strong>Multi-Agent LangGraph System for Professional Architecture Consultation</strong></p>
75
+ <p>✨ 7 AI Specialists | πŸ“ Professional Floorplans | πŸ’° Montreal Market Analysis | πŸ“‹ Building Codes</p>
76
  </div>
77
  """)
78
 
79
+ # API Key input
80
+ api_key = gr.Textbox(
81
+ label="πŸ”‘ OpenAI API Key",
82
+ placeholder="Enter your OpenAI API key (sk-...)",
83
+ type="password",
84
+ info="Required for AI functionality. Not stored or logged."
85
+ )
 
 
 
 
 
86
 
87
+ # Chat interface
88
+ chatbot = gr.Chatbot(
89
+ label="πŸ’¬ Architecture Consultation",
90
+ height=400
91
+ )
92
+
93
+ msg = gr.Textbox(
94
+ label="Your Message",
95
+ placeholder="Ask about home design, budgets, floorplans, Montreal building codes...",
96
+ lines=2
97
+ )
98
 
99
+ # Buttons
100
  with gr.Row():
101
+ send_btn = gr.Button("πŸ“€ Send", variant="primary")
102
+ clear_btn = gr.Button("πŸ”„ Clear", variant="secondary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
+ # Examples
105
+ gr.HTML("""
106
+ <div style="margin: 20px; padding: 15px; background: #f0f0f0; border-radius: 10px;">
107
+ <h4>πŸ’‘ Try these example questions:</h4>
108
+ <ul>
109
+ <li>"I want to design a home but don't know where to start"</li>
110
+ <li>"I have a $800,000 budget for Montreal - is that realistic?"</li>
111
+ <li>"Can you generate a floorplan for a 2500 sq ft house?"</li>
112
+ <li>"What permits do I need in Montreal?"</li>
113
+ </ul>
114
+ </div>
115
+ """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
 
117
  # Event handlers
118
+ msg.submit(
119
+ handle_message,
120
+ inputs=[msg, chatbot, api_key],
121
+ outputs=[chatbot, msg]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  )
123
 
124
  send_btn.click(
125
+ handle_message,
126
+ inputs=[msg, chatbot, api_key],
127
+ outputs=[chatbot, msg]
128
  )
129
 
130
+ clear_btn.click(
131
+ lambda: ([], ""),
132
+ outputs=[chatbot, msg]
 
 
 
 
 
 
 
133
  )
134
 
135
  # Footer
136
  gr.HTML("""
137
  <div style="text-align: center; padding: 20px; margin-top: 30px; border-top: 1px solid #ddd;">
138
+ <p><strong>🏠 Residential Architecture Assistant</strong></p>
139
+ <p>Multi-Agent LangGraph System β€’ Built with Gradio</p>
 
 
 
140
  </div>
141
  """)
142
 
143
  return demo
144
 
145
+ # Launch the interface
146
  if __name__ == "__main__":
147
+ demo = create_simple_interface()
 
 
148
  demo.launch()