ciyidogan commited on
Commit
f454973
·
verified ·
1 Parent(s): e6e1d37

Update chat_handler.py

Browse files
Files changed (1) hide show
  1. chat_handler.py +51 -4
chat_handler.py CHANGED
@@ -1,5 +1,5 @@
1
  """
2
- Flare – Chat Handler (v1.5 · modüler yapı)
3
  ==========================================
4
  """
5
 
@@ -16,6 +16,7 @@ from api_executor import call_api as execute_api
16
  from config_provider import ConfigProvider
17
  from validation_engine import validate
18
  from session import session_store, Session
 
19
  # ───────────────────────── HELPERS ───────────────────────── #
20
  def _trim_response(raw: str) -> str:
21
  """
@@ -38,6 +39,7 @@ def _safe_intent_parse(raw: str) -> tuple[str, str]:
38
  return "", raw
39
  name = m.group(1)
40
  tail = raw[m.end():]
 
41
  return name, tail
42
 
43
  # ───────────────────────── CONFIG ───────────────────────── #
@@ -65,6 +67,8 @@ async def spark_generate(s: Session, prompt: str, user_msg: str) -> str:
65
  }
66
 
67
  log(f"🚀 Calling Spark for session {s.session_id[:8]}...")
 
 
68
  async with httpx.AsyncClient(timeout=60) as client:
69
  response = await client.post(SPARK_URL + "/generate", json=payload)
70
  response.raise_for_status()
@@ -130,6 +134,9 @@ async def chat(body: ChatRequest, x_session_id: str = Header(...)):
130
  if not user_input:
131
  raise HTTPException(400, "Empty message")
132
 
 
 
 
133
  session.add_turn("user", user_input)
134
 
135
  # Get project config
@@ -143,8 +150,10 @@ async def chat(body: ChatRequest, x_session_id: str = Header(...)):
143
 
144
  # Handle based on state
145
  if session.state == "await_param":
 
146
  answer = await _handle_parameter_followup(session, user_input, version)
147
  else:
 
148
  answer = await _handle_new_message(session, user_input, version)
149
 
150
  session.add_turn("assistant", answer)
@@ -175,11 +184,13 @@ async def _handle_new_message(session: Session, user_input: str, version) -> str
175
 
176
  # Empty response fallback
177
  if not raw:
 
178
  return "Üzgünüm, mesajınızı anlayamadım. Lütfen tekrar dener misiniz?"
179
 
180
  # Check for intent
181
  if not raw.startswith("#DETECTED_INTENT"):
182
  # Small talk response
 
183
  return _trim_response(raw)
184
 
185
  # Parse intent
@@ -187,19 +198,26 @@ async def _handle_new_message(session: Session, user_input: str, version) -> str
187
 
188
  # Validate intent
189
  if intent_name not in ALLOWED_INTENTS:
 
190
  return _trim_response(tail) if tail else "Size nasıl yardımcı olabilirim?"
191
 
192
  # Short message guard (less than 3 words usually means incomplete request)
193
  if len(user_input.split()) < 3 and intent_name != "flight-info":
 
194
  return _trim_response(tail) if tail else "Lütfen talebinizi biraz daha detaylandırır mısınız?"
195
 
196
  # Find intent config
197
  intent_config = next((i for i in version.intents if i.name == intent_name), None)
198
  if not intent_config:
 
199
  return "Üzgünüm, bu işlemi gerçekleştiremiyorum."
200
 
201
  # Set intent in session
202
  session.last_intent = intent_name
 
 
 
 
203
 
204
  # Extract parameters
205
  return await _extract_parameters(session, intent_config, user_input)
@@ -207,23 +225,29 @@ async def _handle_new_message(session: Session, user_input: str, version) -> str
207
  async def _handle_parameter_followup(session: Session, user_input: str, version) -> str:
208
  """Handle parameter collection followup"""
209
  if not session.last_intent:
 
210
  session.reset_flow()
211
  return "Üzgünüm, hangi işlem için bilgi istediğimi unuttum. Baştan başlayalım."
212
 
213
  # Get intent config
214
  intent_config = next((i for i in version.intents if i.name == session.last_intent), None)
215
  if not intent_config:
 
216
  session.reset_flow()
217
  return "Bir hata oluştu. Lütfen tekrar deneyin."
218
 
219
  # Try to extract missing parameters
220
  missing = session.awaiting_parameters
 
 
221
  prompt = build_parameter_prompt(intent_config, missing, user_input, session.chat_history)
222
  raw = await spark_generate(session, prompt, user_input)
223
 
224
  if not raw.startswith("#PARAMETERS:"):
225
  # Increment miss count
226
  session.missing_ask_count += 1
 
 
227
  if session.missing_ask_count >= 3:
228
  session.reset_flow()
229
  return "Üzgünüm, istediğiniz bilgileri anlayamadım. Başka bir konuda yardımcı olabilir miyim?"
@@ -232,16 +256,20 @@ async def _handle_parameter_followup(session: Session, user_input: str, version)
232
  # Process parameters
233
  success = _process_parameters(session, intent_config, raw)
234
  if not success:
 
235
  return "Girdiğiniz bilgilerde bir hata var. Lütfen kontrol edip tekrar deneyin."
236
 
237
  # Check if we have all required parameters
238
  missing = _get_missing_parameters(session, intent_config)
 
 
239
  if missing:
240
  session.awaiting_parameters = missing
241
  param = next(p for p in intent_config.parameters if p.name == missing[0])
242
  return f"{param.caption} bilgisini alabilir miyim?"
243
 
244
  # All parameters collected, call API
 
245
  session.state = "call_api"
246
  return await _execute_api_call(session, intent_config)
247
 
@@ -249,8 +277,11 @@ async def _handle_parameter_followup(session: Session, user_input: str, version)
249
  async def _extract_parameters(session: Session, intent_config, user_input: str) -> str:
250
  """Extract parameters from user input"""
251
  missing = _get_missing_parameters(session, intent_config)
 
 
252
  if not missing:
253
  # All parameters already available
 
254
  return await _execute_api_call(session, intent_config)
255
 
256
  # Build parameter extraction prompt
@@ -261,6 +292,9 @@ async def _extract_parameters(session: Session, intent_config, user_input: str)
261
  success = _process_parameters(session, intent_config, raw)
262
  if success:
263
  missing = _get_missing_parameters(session, intent_config)
 
 
 
264
 
265
  if missing:
266
  # Still missing parameters
@@ -268,25 +302,32 @@ async def _extract_parameters(session: Session, intent_config, user_input: str)
268
  session.awaiting_parameters = missing
269
  session.missing_ask_count = 0
270
  param = next(p for p in intent_config.parameters if p.name == missing[0])
 
271
  return f"{param.caption} bilgisini alabilir miyim?"
272
 
273
  # All parameters collected
 
274
  return await _execute_api_call(session, intent_config)
275
 
276
  def _get_missing_parameters(session: Session, intent_config) -> List[str]:
277
  """Get list of missing required parameters"""
278
- return [
279
  p.name for p in intent_config.parameters
280
  if p.required and p.variable_name not in session.variables
281
  ]
 
 
282
 
283
  def _process_parameters(session: Session, intent_config, raw: str) -> bool:
284
  """Process parameter extraction response"""
285
  try:
286
  json_str = raw[len("#PARAMETERS:"):]
 
287
  data = json.loads(json_str)
288
 
289
  extracted = data.get("extracted", [])
 
 
290
  any_valid = False
291
 
292
  for param_data in extracted:
@@ -294,6 +335,7 @@ def _process_parameters(session: Session, intent_config, raw: str) -> bool:
294
  param_value = param_data.get("value")
295
 
296
  if not param_name or not param_value:
 
297
  continue
298
 
299
  # Find parameter config
@@ -302,13 +344,14 @@ def _process_parameters(session: Session, intent_config, raw: str) -> bool:
302
  None
303
  )
304
  if not param_config:
 
305
  continue
306
 
307
  # Validate parameter
308
  if validate(str(param_value), param_config):
309
  session.variables[param_config.variable_name] = str(param_value)
310
  any_valid = True
311
- log(f"✅ Extracted {param_name}={param_value}")
312
  else:
313
  log(f"❌ Invalid {param_name}={param_value}")
314
 
@@ -327,14 +370,17 @@ async def _execute_api_call(session: Session, intent_config) -> str:
327
  api_config = cfg.get_api(api_name)
328
 
329
  if not api_config:
 
330
  session.reset_flow()
331
  return intent_config.fallback_error_prompt or "İşlem başarısız oldu."
332
 
333
  log(f"📡 Calling API: {api_name}")
 
334
 
335
  # Execute API call with session
336
- response = execute_api(api_config, session) # Pass session instead of just variables
337
  api_json = response.json()
 
338
 
339
  # Humanize response
340
  session.state = "humanize"
@@ -351,6 +397,7 @@ async def _execute_api_call(session: Session, intent_config) -> str:
351
  return f"İşlem tamamlandı: {api_json}"
352
 
353
  except requests.exceptions.Timeout:
 
354
  session.reset_flow()
355
  return intent_config.fallback_timeout_prompt or "İşlem zaman aşımına uğradı."
356
  except Exception as e:
 
1
  """
2
+ Flare – Chat Handler (v1.6 · detaylı log)
3
  ==========================================
4
  """
5
 
 
16
  from config_provider import ConfigProvider
17
  from validation_engine import validate
18
  from session import session_store, Session
19
+
20
  # ───────────────────────── HELPERS ───────────────────────── #
21
  def _trim_response(raw: str) -> str:
22
  """
 
39
  return "", raw
40
  name = m.group(1)
41
  tail = raw[m.end():]
42
+ log(f"🎯 Parsed intent: {name}")
43
  return name, tail
44
 
45
  # ───────────────────────── CONFIG ───────────────────────── #
 
67
  }
68
 
69
  log(f"🚀 Calling Spark for session {s.session_id[:8]}...")
70
+ log(f"📋 Prompt preview (first 200 chars): {prompt[:200]}...")
71
+
72
  async with httpx.AsyncClient(timeout=60) as client:
73
  response = await client.post(SPARK_URL + "/generate", json=payload)
74
  response.raise_for_status()
 
134
  if not user_input:
135
  raise HTTPException(400, "Empty message")
136
 
137
+ log(f"💬 User input: {user_input}")
138
+ log(f"📊 Session state: {session.state}, last_intent: {session.last_intent}")
139
+
140
  session.add_turn("user", user_input)
141
 
142
  # Get project config
 
150
 
151
  # Handle based on state
152
  if session.state == "await_param":
153
+ log(f"🔄 Handling parameter followup for missing: {session.awaiting_parameters}")
154
  answer = await _handle_parameter_followup(session, user_input, version)
155
  else:
156
+ log("🆕 Handling new message")
157
  answer = await _handle_new_message(session, user_input, version)
158
 
159
  session.add_turn("assistant", answer)
 
184
 
185
  # Empty response fallback
186
  if not raw:
187
+ log("⚠️ Empty response from Spark")
188
  return "Üzgünüm, mesajınızı anlayamadım. Lütfen tekrar dener misiniz?"
189
 
190
  # Check for intent
191
  if not raw.startswith("#DETECTED_INTENT"):
192
  # Small talk response
193
+ log("💬 No intent detected, returning small talk")
194
  return _trim_response(raw)
195
 
196
  # Parse intent
 
198
 
199
  # Validate intent
200
  if intent_name not in ALLOWED_INTENTS:
201
+ log(f"⚠️ Invalid intent: {intent_name}")
202
  return _trim_response(tail) if tail else "Size nasıl yardımcı olabilirim?"
203
 
204
  # Short message guard (less than 3 words usually means incomplete request)
205
  if len(user_input.split()) < 3 and intent_name != "flight-info":
206
+ log(f"⚠️ Message too short ({len(user_input.split())} words) for intent {intent_name}")
207
  return _trim_response(tail) if tail else "Lütfen talebinizi biraz daha detaylandırır mısınız?"
208
 
209
  # Find intent config
210
  intent_config = next((i for i in version.intents if i.name == intent_name), None)
211
  if not intent_config:
212
+ log(f"❌ Intent config not found for: {intent_name}")
213
  return "Üzgünüm, bu işlemi gerçekleştiremiyorum."
214
 
215
  # Set intent in session
216
  session.last_intent = intent_name
217
+ log(f"✅ Intent set: {intent_name}")
218
+
219
+ # Log intent parameters
220
+ log(f"📋 Intent parameters: {[p.name for p in intent_config.parameters]}")
221
 
222
  # Extract parameters
223
  return await _extract_parameters(session, intent_config, user_input)
 
225
  async def _handle_parameter_followup(session: Session, user_input: str, version) -> str:
226
  """Handle parameter collection followup"""
227
  if not session.last_intent:
228
+ log("⚠️ No last intent in session")
229
  session.reset_flow()
230
  return "Üzgünüm, hangi işlem için bilgi istediğimi unuttum. Baştan başlayalım."
231
 
232
  # Get intent config
233
  intent_config = next((i for i in version.intents if i.name == session.last_intent), None)
234
  if not intent_config:
235
+ log(f"❌ Intent config not found for: {session.last_intent}")
236
  session.reset_flow()
237
  return "Bir hata oluştu. Lütfen tekrar deneyin."
238
 
239
  # Try to extract missing parameters
240
  missing = session.awaiting_parameters
241
+ log(f"🔍 Trying to extract missing params: {missing}")
242
+
243
  prompt = build_parameter_prompt(intent_config, missing, user_input, session.chat_history)
244
  raw = await spark_generate(session, prompt, user_input)
245
 
246
  if not raw.startswith("#PARAMETERS:"):
247
  # Increment miss count
248
  session.missing_ask_count += 1
249
+ log(f"⚠️ No parameters extracted, miss count: {session.missing_ask_count}")
250
+
251
  if session.missing_ask_count >= 3:
252
  session.reset_flow()
253
  return "Üzgünüm, istediğiniz bilgileri anlayamadım. Başka bir konuda yardımcı olabilir miyim?"
 
256
  # Process parameters
257
  success = _process_parameters(session, intent_config, raw)
258
  if not success:
259
+ log("❌ Parameter processing failed")
260
  return "Girdiğiniz bilgilerde bir hata var. Lütfen kontrol edip tekrar deneyin."
261
 
262
  # Check if we have all required parameters
263
  missing = _get_missing_parameters(session, intent_config)
264
+ log(f"📊 Still missing params: {missing}")
265
+
266
  if missing:
267
  session.awaiting_parameters = missing
268
  param = next(p for p in intent_config.parameters if p.name == missing[0])
269
  return f"{param.caption} bilgisini alabilir miyim?"
270
 
271
  # All parameters collected, call API
272
+ log("✅ All parameters collected, calling API")
273
  session.state = "call_api"
274
  return await _execute_api_call(session, intent_config)
275
 
 
277
  async def _extract_parameters(session: Session, intent_config, user_input: str) -> str:
278
  """Extract parameters from user input"""
279
  missing = _get_missing_parameters(session, intent_config)
280
+ log(f"🔍 Missing parameters: {missing}")
281
+
282
  if not missing:
283
  # All parameters already available
284
+ log("✅ All parameters already available")
285
  return await _execute_api_call(session, intent_config)
286
 
287
  # Build parameter extraction prompt
 
292
  success = _process_parameters(session, intent_config, raw)
293
  if success:
294
  missing = _get_missing_parameters(session, intent_config)
295
+ log(f"📊 After extraction, missing: {missing}")
296
+ else:
297
+ log("⚠️ No #PARAMETERS tag in response")
298
 
299
  if missing:
300
  # Still missing parameters
 
302
  session.awaiting_parameters = missing
303
  session.missing_ask_count = 0
304
  param = next(p for p in intent_config.parameters if p.name == missing[0])
305
+ log(f"❓ Asking for parameter: {param.name} ({param.caption})")
306
  return f"{param.caption} bilgisini alabilir miyim?"
307
 
308
  # All parameters collected
309
+ log("✅ All parameters collected after extraction")
310
  return await _execute_api_call(session, intent_config)
311
 
312
  def _get_missing_parameters(session: Session, intent_config) -> List[str]:
313
  """Get list of missing required parameters"""
314
+ missing = [
315
  p.name for p in intent_config.parameters
316
  if p.required and p.variable_name not in session.variables
317
  ]
318
+ log(f"📊 Session variables: {list(session.variables.keys())}")
319
+ return missing
320
 
321
  def _process_parameters(session: Session, intent_config, raw: str) -> bool:
322
  """Process parameter extraction response"""
323
  try:
324
  json_str = raw[len("#PARAMETERS:"):]
325
+ log(f"🔍 Parsing parameters JSON: {json_str[:200]}")
326
  data = json.loads(json_str)
327
 
328
  extracted = data.get("extracted", [])
329
+ log(f"📦 Extracted data: {extracted}")
330
+
331
  any_valid = False
332
 
333
  for param_data in extracted:
 
335
  param_value = param_data.get("value")
336
 
337
  if not param_name or not param_value:
338
+ log(f"⚠️ Invalid param data: {param_data}")
339
  continue
340
 
341
  # Find parameter config
 
344
  None
345
  )
346
  if not param_config:
347
+ log(f"⚠️ Parameter config not found for: {param_name}")
348
  continue
349
 
350
  # Validate parameter
351
  if validate(str(param_value), param_config):
352
  session.variables[param_config.variable_name] = str(param_value)
353
  any_valid = True
354
+ log(f"✅ Extracted {param_name}={param_value} → {param_config.variable_name}")
355
  else:
356
  log(f"❌ Invalid {param_name}={param_value}")
357
 
 
370
  api_config = cfg.get_api(api_name)
371
 
372
  if not api_config:
373
+ log(f"❌ API config not found: {api_name}")
374
  session.reset_flow()
375
  return intent_config.fallback_error_prompt or "İşlem başarısız oldu."
376
 
377
  log(f"📡 Calling API: {api_name}")
378
+ log(f"📦 API variables: {session.variables}")
379
 
380
  # Execute API call with session
381
+ response = execute_api(api_config, session)
382
  api_json = response.json()
383
+ log(f"✅ API response: {api_json}")
384
 
385
  # Humanize response
386
  session.state = "humanize"
 
397
  return f"İşlem tamamlandı: {api_json}"
398
 
399
  except requests.exceptions.Timeout:
400
+ log(f"⏱️ API timeout: {api_name}")
401
  session.reset_flow()
402
  return intent_config.fallback_timeout_prompt or "İşlem zaman aşımına uğradı."
403
  except Exception as e: