lokesh341 commited on
Commit
369194d
·
verified ·
1 Parent(s): 3a29371

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +242 -122
app.py CHANGED
@@ -3,6 +3,9 @@ from simple_salesforce import Salesforce
3
  from dotenv import load_dotenv
4
  import os
5
  import logging
 
 
 
6
 
7
  # Load environment variables
8
  load_dotenv()
@@ -31,79 +34,190 @@ def get_salesforce_connection():
31
  # Initialize Salesforce connection
32
  sf = get_salesforce_connection()
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  @app.route('/')
35
  def index():
36
  return render_template('index.html')
37
 
38
- # Fetch items from Sector_Detail__c and Menu_Item__c for dietary preferences
39
  @app.route('/get_menu_items', methods=['POST'])
40
  def get_menu_items():
41
  global sf
42
  if not sf:
43
  sf = get_salesforce_connection()
44
  if not sf:
45
- logger.error("Salesforce connection failed after retry")
46
  return jsonify({"error": "Unable to connect to Salesforce"}), 500
47
 
48
- dietary_preference = request.json.get('dietary_preference', 'both').lower()
 
 
49
  try:
50
- # Query Sector_Detail__c
51
- soql_sector = "SELECT Name, Image_URL__c, Category__c, Description__c FROM Sector_Detail__c"
52
- if dietary_preference == 'vegetarian':
53
- soql_sector += " WHERE Category__c = 'Veg'"
54
- elif dietary_preference == 'non-vegetarian':
55
- soql_sector += " WHERE Category__c = 'Non-Veg'"
56
- soql_sector += " LIMIT 200"
57
-
58
- logger.info(f"Executing SOQL query for Sector_Detail__c: {soql_sector}")
59
- result_sector = sf.query(soql_sector)
60
- sector_items = [
61
- {
62
- "name": record['Name'],
63
- "image_url": record.get('Image_URL__c', ''),
64
- "category": record.get('Category__c', ''),
65
- "description": record.get('Description__c', 'No description available'),
66
- "source": "Sector_Detail__c"
67
- }
68
- for record in result_sector['records'] if 'Name' in record
69
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- # Query Menu_Item__c
72
- soql_menu = "SELECT Name, Description__c, Image1__c, Ingredientsinfo__c, NutritionalInfo__c, Price__c, Sector__c, Spice_Levels__c, Veg_NonVeg__c, Category__c, Dynamic_Dish__c FROM Menu_Item__c"
73
- if dietary_preference == 'vegetarian':
74
- soql_menu += " WHERE Veg_NonVeg__c = 'Vegetarian'"
75
- elif dietary_preference == 'non-vegetarian':
76
- soql_menu += " WHERE Veg_NonVeg__c = 'Non-Vegetarian'"
77
- soql_menu += " LIMIT 200"
78
-
79
- logger.info(f"Executing SOQL query for Menu_Item__c: {soql_menu}")
80
- result_menu = sf.query(soql_menu)
81
- menu_items = [
82
- {
83
- "name": record['Name'],
84
- "description": record.get('Description__c', 'No description available'),
85
- "image_url": record.get('Image1__c', ''),
86
- "ingredients": record.get('Ingredientsinfo__c', ''),
87
- "nutritional_info": record.get('NutritionalInfo__c', ''),
88
- "price": record.get('Price__c', 0.0),
89
- "sector": record.get('Sector__c', ''),
90
- "spice_levels": record.get('Spice_Levels__c', ''),
91
- "veg_nonveg": record.get('Veg_NonVeg__c', ''),
92
- "category": record.get('Category__c', ''),
93
- "dynamic_dish": record.get('Dynamic_Dish__c', False),
94
- "source": "Menu_Item__c"
95
- }
96
- for record in result_menu['records'] if 'Name' in record
97
- ]
98
 
99
- items = sector_items + menu_items
100
- logger.info(f"Fetched {len(items)} items (Sector_Detail__c: {len(sector_items)}, Menu_Item__c: {len(menu_items)}) for {dietary_preference}")
101
- return jsonify({"menu_items": items})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  except Exception as e:
103
- logger.error(f"Failed to fetch items: {str(e)}")
104
- return jsonify({"error": f"Failed to fetch items from Salesforce: {str(e)}"}), 500
105
 
106
- # Fetch suggestions from Ingredient_Object__c
107
  @app.route('/suggest_items', methods=['POST'])
108
  def suggest_items():
109
  global sf
@@ -127,12 +241,11 @@ def suggest_items():
127
  logger.info(f"Fetched {len(suggestions)} suggestions for '{search_term}'")
128
  return jsonify({"suggestions": suggestions})
129
  except Exception as e:
130
- logger.error(f"Failed to fetch suggestions: {str(e)}")
131
- return jsonify({"error": "Failed to fetch suggestions from Salesforce"}), 500
132
 
133
- # Fetch item details from Menu_Item__c by name
134
- @app.route('/get_menu_item_details', methods=['POST'])
135
- def get_menu_item_details():
136
  global sf
137
  if not sf:
138
  sf = get_salesforce_connection()
@@ -144,70 +257,24 @@ def get_menu_item_details():
144
  return jsonify({"error": "Item name is required"}), 400
145
 
146
  try:
147
- soql = f"SELECT Name, Description__c, Image1__c, Ingredientsinfo__c, NutritionalInfo__c, Price__c, Sector__c, Spice_Levels__c, Veg_NonVeg__c, Category__c, Dynamic_Dish__c FROM Menu_Item__c WHERE Name LIKE '%{item_name}%' LIMIT 1"
148
  logger.info(f"Executing SOQL query: {soql}")
149
  result = sf.query(soql)
150
 
151
  if result['totalSize'] == 0:
152
- return jsonify({"error": f"No item found matching '{item_name}' in Menu_Item__c"}), 404
153
 
154
  record = result['records'][0]
155
  item_details = {
156
- "name": record.get('Name', ''),
157
- "description": record.get('Description__c', 'No description available'),
158
- "image_url": record.get('Image1__c', 'https://via.placeholder.com/30'),
159
- "ingredients": record.get('Ingredientsinfo__c', ''),
160
- "nutritional_info": record.get('NutritionalInfo__c', ''),
161
- "price": record.get('Price__c', 0.0),
162
- "sector": record.get('Sector__c', ''),
163
- "spice_levels": record.get('Spice_Levels__c', ''),
164
- "veg_nonveg": record.get('Veg_NonVeg__c', ''),
165
- "category": record.get('Category__c', ''),
166
- "dynamic_dish": record.get('Dynamic_Dish__c', False),
167
- "source": "Menu_Item__c"
168
- }
169
- logger.info(f"Fetched details for '{item_name}' from Menu_Item__c")
170
- return jsonify({"item_details": item_details})
171
- except Exception as e:
172
- logger.error(f"Failed to fetch item details from Menu_Item__c: {str(e)}")
173
- return jsonify({"error": f"Failed to fetch item details from Salesforce: {str(e)}"}), 500
174
-
175
- # Fetch item details from Sector_Detail__c by name
176
- @app.route('/get_sector_item_details', methods=['POST'])
177
- def get_sector_item_details():
178
- global sf
179
- if not sf:
180
- sf = get_salesforce_connection()
181
- if not sf:
182
- return jsonify({"error": "Unable to connect to Salesforce"}), 500
183
-
184
- item_name = request.json.get('item_name', '').strip()
185
- if not item_name:
186
- return jsonify({"error": "Item name is required"}), 400
187
-
188
- try:
189
- soql = f"SELECT Name, Image_URL__c, Category__c, Description__c FROM Sector_Detail__c WHERE Name LIKE '%{item_name}%' LIMIT 1"
190
- logger.info(f"Executing SOQL query: {soql}")
191
- result = sf.query(soql)
192
-
193
- if result['totalSize'] == 0:
194
- return jsonify({"error": f"No item found matching '{item_name}' in Sector_Detail__c"}), 404
195
-
196
- record = result['records'][0]
197
- item_details = {
198
- "name": record.get('Name', ''),
199
- "image_url": record.get('Image_URL__c', 'https://via.placeholder.com/30'),
200
- "category": record.get('Category__c', 'Unknown'),
201
- "description": record.get('Description__c', 'No description available'),
202
- "source": "Sector_Detail__c"
203
  }
204
- logger.info(f"Fetched details for '{item_name}' from Sector_Detail__c")
205
  return jsonify({"item_details": item_details})
206
  except Exception as e:
207
- logger.error(f"Failed to fetch item details from Sector_Detail__c: {str(e)}")
208
- return jsonify({"error": f"Failed to fetch item details from Salesforce: {str(e)}"}), 500
209
 
210
- # Submit selected items to Ingredient_Object__c
211
  @app.route('/submit_items', methods=['POST'])
212
  def submit_items():
213
  global sf
@@ -217,22 +284,75 @@ def submit_items():
217
  return jsonify({"error": "Unable to connect to Salesforce"}), 500
218
 
219
  items = request.json.get('items', [])
 
220
  if not items:
221
  return jsonify({"error": "No items to submit"}), 400
222
 
223
  try:
 
 
 
 
224
  for item in items:
225
- logger.info(f"Submitting item: {item}")
226
  sf.Ingredient_Object__c.create({
227
- 'Ingredient_Name__c': item['name'],
228
- 'Category__c': item.get('category', 'Unknown'),
229
- 'Description__c': item.get('description', 'No description available')
 
 
230
  })
231
- logger.info(f"Successfully submitted item to Ingredient_Object__c: {item['name']}")
232
- return jsonify({"success": f"Successfully submitted {len(items)} items to Salesforce"})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
233
  except Exception as e:
234
- logger.error(f"Failed to submit items: {str(e)}")
235
- return jsonify({"error": f"Failed to submit items to Salesforce: {str(e)}"}), 500
 
 
 
 
 
 
 
 
 
 
 
236
 
237
  if __name__ == '__main__':
238
  app.run(debug=True, host='0.0.0.0', port=7860)
 
3
  from dotenv import load_dotenv
4
  import os
5
  import logging
6
+ import uuid
7
+ from datetime import datetime
8
+ from openai import OpenAI
9
 
10
  # Load environment variables
11
  load_dotenv()
 
34
  # Initialize Salesforce connection
35
  sf = get_salesforce_connection()
36
 
37
+ # Initialize OpenAI client
38
+ openai_api_key = os.getenv('OPENAI_API_KEY')
39
+ if not openai_api_key:
40
+ logger.error("OPENAI_API_KEY not found in .env. ChatGPT functionality disabled.")
41
+ client = None
42
+ else:
43
+ try:
44
+ client = OpenAI(api_key=openai_api_key)
45
+ test_response = client.chat.completions.create(
46
+ model="gpt-3.5-turbo",
47
+ messages=[{"role": "user", "content": "Test API key"}]
48
+ )
49
+ logger.info("OpenAI API key validated successfully")
50
+ except Exception as e:
51
+ logger.error(f"Invalid OpenAI API key or connection issue: {e}")
52
+ client = None
53
+
54
+ # Conversation storage
55
+ conversation_sessions = {}
56
+
57
+ def is_restaurant_related(query):
58
+ keywords = ['use', 'uses', 'dish', 'recipe', 'ingredient', 'food', 'menu', 'vegetarian', 'non-vegetarian',
59
+ 'rice', 'chicken', 'pasta', 'veggie', 'mutton', 'lamb', 'beef', 'pork', 'fish', 'seafood',
60
+ 'ingredients', 'nutrition', 'nutritional', 'info', 'message', 'messages']
61
+ return bool(query.strip() and any(keyword in query.lower() for keyword in keywords)) or any(item in query.lower() for item in ['mutton', 'rice', 'chicken'])
62
+
63
+ def get_chatgpt_response(prompt, session_id):
64
+ if not client:
65
+ logger.warning("No OpenAI client available, using mock ChatGPT response")
66
+ if any(item in prompt.lower() for item in ['mutton', 'rice', 'chicken']):
67
+ return f"{prompt.capitalize()} is great for curries or roasts in a restaurant!"
68
+ return "I can help with food! Try 'uses of mutton' or 'ingredients for rice'."
69
+
70
+ if session_id not in conversation_sessions:
71
+ conversation_sessions[session_id] = [
72
+ {"role": "system", "content": "You are a restaurant culinary assistant. Respond only to queries about ingredients, dishes, or recipes. Provide concise, friendly answers. For unclear queries, suggest: 'Try 'uses of mutton' or 'ingredients for rice'.'"}
73
+ ]
74
+
75
+ prompt = prompt.strip().lower()
76
+ logger.info(f"Processing prompt: {prompt}")
77
+ if not is_restaurant_related(prompt):
78
+ logger.info(f"Off-topic or empty query: {prompt}")
79
+ return "I can help with food! Try 'uses of mutton' or 'ingredients for rice'."
80
+
81
+ intent = "uses"
82
+ item = prompt
83
+ if "what is the use of" in prompt or "uses of" in prompt:
84
+ item = prompt.replace("what is the use of ", "").replace("uses of ", "").strip() or prompt
85
+ prompt = f"Provide the culinary uses of '{item}' for a restaurant. Be concise and friendly. If unknown, say 'Great for many dishes!'"
86
+ elif any(word in prompt for word in ['suggest', 'recipe', 'dish']):
87
+ intent = "suggest"
88
+ prompt = f"Suggest a restaurant dish based on: {prompt}. Include ingredients and be concise."
89
+ elif any(word in prompt for word in ['ingredients', 'ingredient']):
90
+ intent = "ingredients"
91
+ item = prompt.replace("ingredients for ", "").replace("ingredient of ", "").strip() or prompt
92
+ prompt = f"List common ingredients for a restaurant dish using '{item}'. Be concise and realistic."
93
+ elif any(word in prompt for word in ['nutrition', 'nutritional', 'info']):
94
+ intent = "nutrition"
95
+ item = prompt.replace("nutrition of ", "").replace("nutritional info for ", "").strip() or prompt
96
+ prompt = f"Provide a concise, approximate nutritional overview (calories, protein, fat, carbs) for a restaurant portion of '{item}'. Use general culinary knowledge and keep it friendly."
97
+ elif any(item in prompt for item in ['mutton', 'rice', 'chicken', 'pasta', 'veggie', 'lamb', 'beef', 'pork', 'fish', 'seafood']):
98
+ prompt = f"Provide the culinary uses of '{item}' for a restaurant. Be concise and friendly. If unknown, say 'Great for many dishes!'"
99
+ else:
100
+ logger.info(f"Unclear intent, defaulting to uses for: {prompt}")
101
+ prompt = f"Provide the culinary uses of '{prompt}' for a restaurant. Be concise and friendly. If unknown, say 'Great for many dishes!'"
102
+
103
+ conversation_sessions[session_id].append({"role": "user", "content": prompt})
104
+
105
+ try:
106
+ response = client.chat.completions.create(
107
+ model="gpt-3.5-turbo",
108
+ messages=conversation_sessions[session_id],
109
+ max_tokens=150,
110
+ timeout=10
111
+ )
112
+ reply = response.choices[0].message.content.strip()
113
+ conversation_sessions[session_id].append({"role": "assistant", "content": reply})
114
+ logger.info(f"ChatGPT response for '{prompt}': {reply}")
115
+ return reply
116
+ except Exception as e:
117
+ logger.error(f"OpenAI API error: {e}")
118
+ return f"Sorry, API failed. Mock response: {prompt.capitalize()} is great for curries or roasts!"
119
+
120
  @app.route('/')
121
  def index():
122
  return render_template('index.html')
123
 
 
124
  @app.route('/get_menu_items', methods=['POST'])
125
  def get_menu_items():
126
  global sf
127
  if not sf:
128
  sf = get_salesforce_connection()
129
  if not sf:
 
130
  return jsonify({"error": "Unable to connect to Salesforce"}), 500
131
 
132
+ data = request.json
133
+ dietary_preference = data.get('dietary_preference', 'both').lower()
134
+ search_term = data.get('search_term', '').strip()
135
  try:
136
+ items = []
137
+ if not search_term:
138
+ soql = "SELECT Name, Image_URL__c, Category__c, Description__c FROM Sector_Detail__c"
139
+ if dietary_preference == 'vegetarian':
140
+ soql += " WHERE Category__c = 'Veg'"
141
+ elif dietary_preference == 'non-vegetarian':
142
+ soql += " WHERE Category__c = 'Non-Veg'"
143
+ soql += " LIMIT 200"
144
+ result = sf.query(soql)
145
+ items = [
146
+ {
147
+ "name": r['Name'],
148
+ "image_url": r.get('Image_URL__c', ''),
149
+ "category": r.get('Category__c', ''),
150
+ "description": r.get('Description__c', 'No description'),
151
+ "source": "Sector_Detail__c"
152
+ }
153
+ for r in result['records'] if 'Name' in r
154
+ ]
155
+ else:
156
+ soql_menu = "SELECT Name, Description__c, Image1__c, Ingredientsinfo__c, NutritionalInfo__c, Price__c, Sector__c, Spice_Levels__c, Veg_NonVeg__c, Category__c, Dynamic_Dish__c FROM Menu_Item__c"
157
+ soql_menu += f" WHERE Name LIKE '%{search_term}%' OR Ingredientsinfo__c LIKE '%{search_term}%'"
158
+ if dietary_preference == 'vegetarian':
159
+ soql_menu += " AND Veg_NonVeg__c = 'Vegetarian'"
160
+ elif dietary_preference == 'non-vegetarian':
161
+ soql_menu += " AND Veg_NonVeg__c = 'Non-Vegetarian'"
162
+ soql_menu += " LIMIT 200"
163
+ logger.info(f"Executing SOQL query for Menu_Item__c: {soql_menu}")
164
+ result_menu = sf.query(soql_menu)
165
+ menu_items = [
166
+ {
167
+ "name": record['Name'],
168
+ "description": record.get('Description__c', 'No description available'),
169
+ "image_url": record.get('Image1__c', ''),
170
+ "ingredients": record.get('Ingredientsinfo__c', ''),
171
+ "nutritional_info": record.get('NutritionalInfo__c', ''),
172
+ "price": record.get('Price__c', 0.0),
173
+ "sector": record.get('Sector__c', ''),
174
+ "spice_levels": record.get('Spice_Levels__c', ''),
175
+ "veg_nonveg": record.get('Veg_NonVeg__c', ''),
176
+ "category": record.get('Category__c', ''),
177
+ "dynamic_dish": record.get('Dynamic_Dish__c', False),
178
+ "source": "Menu_Item__c"
179
+ }
180
+ for record in result_menu['records'] if 'Name' in record
181
+ ]
182
+ items.extend(menu_items)
183
+ return jsonify({"menu_items": items})
184
+ except Exception as e:
185
+ logger.error(f"Failed to fetch items: {e}")
186
+ return jsonify({"error": f"Failed to fetch items: {e}"}), 500
187
 
188
+ @app.route('/get_sector_item_details', methods=['POST'])
189
+ def get_sector_item_details():
190
+ global sf
191
+ if not sf:
192
+ sf = get_salesforce_connection()
193
+ if not sf:
194
+ return jsonify({"error": "Unable to connect to Salesforce"}), 500
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
 
196
+ item_name = request.json.get('item_name', '').strip()
197
+ if not item_name:
198
+ return jsonify({"error": "Item name is required"}), 400
199
+
200
+ try:
201
+ soql = f"SELECT Name, Image_URL__c, Category__c, Description__c FROM Sector_Detail__c WHERE Name LIKE '%{item_name}%' LIMIT 1"
202
+ logger.info(f"Executing SOQL query: {soql}")
203
+ result = sf.query(soql)
204
+
205
+ if result['totalSize'] == 0:
206
+ return jsonify({"error": f"No item found matching '{item_name}' in Sector_Detail__c"}), 404
207
+
208
+ record = result['records'][0]
209
+ item_details = {
210
+ "name": record.get('Name', ''),
211
+ "image_url": record.get('Image_URL__c', 'https://via.placeholder.com/30'),
212
+ "category": record.get('Category__c', ''),
213
+ "description": record.get('Description__c', 'No description available')
214
+ }
215
+ logger.info(f"Fetched details for '{item_name}' from Sector_Detail__c")
216
+ return jsonify({"item_details": item_details})
217
  except Exception as e:
218
+ logger.error(f"Failed to fetch item details from Sector_Detail__c: {e}")
219
+ return jsonify({"error": f"Failed to fetch item details: {e}"}), 500
220
 
 
221
  @app.route('/suggest_items', methods=['POST'])
222
  def suggest_items():
223
  global sf
 
241
  logger.info(f"Fetched {len(suggestions)} suggestions for '{search_term}'")
242
  return jsonify({"suggestions": suggestions})
243
  except Exception as e:
244
+ logger.error(f"Failed to fetch suggestions: {e}")
245
+ return jsonify({"error": f"Failed to fetch suggestions: {e}"}), 500
246
 
247
+ @app.route('/get_item_details', methods=['POST'])
248
+ def get_item_details():
 
249
  global sf
250
  if not sf:
251
  sf = get_salesforce_connection()
 
257
  return jsonify({"error": "Item name is required"}), 400
258
 
259
  try:
260
+ soql = f"SELECT Ingredient_Name__c, Image_URL__c FROM Ingredient_Object__c WHERE Ingredient_Name__c LIKE '%{item_name}%' LIMIT 1"
261
  logger.info(f"Executing SOQL query: {soql}")
262
  result = sf.query(soql)
263
 
264
  if result['totalSize'] == 0:
265
+ return jsonify({"error": f"No item found matching '{item_name}' in Ingredient_Object__c"}), 404
266
 
267
  record = result['records'][0]
268
  item_details = {
269
+ "name": record.get('Ingredient_Name__c', ''),
270
+ "image_url": record.get('Image_URL__c', '')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
271
  }
272
+ logger.info(f"Fetched details for '{item_name}'")
273
  return jsonify({"item_details": item_details})
274
  except Exception as e:
275
+ logger.error(f"Failed to fetch item details: {e}")
276
+ return jsonify({"error": f"Failed to fetch item details: {e}"}), 500
277
 
 
278
  @app.route('/submit_items', methods=['POST'])
279
  def submit_items():
280
  global sf
 
284
  return jsonify({"error": "Unable to connect to Salesforce"}), 500
285
 
286
  items = request.json.get('items', [])
287
+ custom_order_name = request.json.get('custom_order_name', '')
288
  if not items:
289
  return jsonify({"error": "No items to submit"}), 400
290
 
291
  try:
292
+ ingredient_name = custom_order_name or f"Order_{datetime.now().strftime('%Y%m%d')}_{uuid.uuid4().hex[:8]}"
293
+ item_names = ', '.join(item['name'] for item in items)
294
+ description = f"Contains: {item_names}"
295
+
296
  for item in items:
 
297
  sf.Ingredient_Object__c.create({
298
+ 'Ingredient_Name__c': ingredient_name,
299
+ 'Category__c': item.get('category', ''),
300
+ 'Description__c': f"{item.get('description', 'No description')} - {description}",
301
+ 'Image_URL__c': item.get('image_url', ''),
302
+ 'Quantity__c': item.get('quantity', 1)
303
  })
304
+
305
+ return jsonify({"success": f"Submitted {len(items)} items under {ingredient_name}", "ingredient_name": ingredient_name})
306
+ except Exception as e:
307
+ logger.error(f"Failed to submit items: {e}")
308
+ return jsonify({"error": f"Failed to submit items: {e}"}), 500
309
+
310
+ @app.route('/get_item_info', methods=['POST'])
311
+ def get_item_info():
312
+ global sf, client
313
+ item_name = request.json.get('item_name', '').strip()
314
+ if not item_name or not client:
315
+ return jsonify({"error": "Item name required or OpenAI unavailable"}), 400
316
+
317
+ try:
318
+ soql = f"SELECT Name, Description__c FROM Sector_Detail__c WHERE Name LIKE '%{item_name}%' LIMIT 1"
319
+ result = sf.query(soql)
320
+ if result['totalSize'] == 0:
321
+ return jsonify({"error": f"No item found matching '{item_name}'"}), 404
322
+
323
+ record = result['records'][0]
324
+ base_info = record.get('Description__c', 'No description available')
325
+
326
+ prompt = f"Based on general culinary knowledge, provide a concise list of common ingredients and an approximate nutritional overview (calories, protein, fat, carbs) for a restaurant portion of '{item_name}'. Use realistic values and keep it friendly."
327
+ response = client.chat.completions.create(
328
+ model="gpt-3.5-turbo",
329
+ messages=[{"role": "user", "content": prompt}],
330
+ max_tokens=150,
331
+ timeout=10
332
+ )
333
+ ai_response = response.choices[0].message.content.strip()
334
+
335
+ item_info = {
336
+ "name": record['Name'],
337
+ "description": base_info,
338
+ "details": ai_response
339
+ }
340
+ logger.info(f"Generated info for '{item_name}'")
341
+ return jsonify({"item_info": item_info})
342
  except Exception as e:
343
+ logger.error(f"Failed to get item info: {e}")
344
+ return jsonify({"error": f"Failed to get item info: {e}"}), 500
345
+
346
+ @app.route('/chat', methods=['POST'])
347
+ def chat():
348
+ user_message = request.json.get('message', '').strip()
349
+ session_id = request.json.get('session_id', 'default')
350
+ if not user_message:
351
+ return jsonify({"error": "No message provided"}), 400
352
+
353
+ response = get_chatgpt_response(user_message, session_id)
354
+ logger.info(f"Chat response sent: {response}")
355
+ return jsonify({"response": response, "search_term": user_message})
356
 
357
  if __name__ == '__main__':
358
  app.run(debug=True, host='0.0.0.0', port=7860)