Spaces:
Running
Running
Refactor respond function for improved error handling and response formatting
Browse files
app.py
CHANGED
|
@@ -343,7 +343,7 @@ def detect_language(text):
|
|
| 343 |
except Exception as e:
|
| 344 |
print(f"Language detection error: {str(e)}. Defaulting to English.")
|
| 345 |
return "en"
|
| 346 |
-
|
| 347 |
def respond(
|
| 348 |
message,
|
| 349 |
history,
|
|
@@ -354,176 +354,53 @@ def respond(
|
|
| 354 |
top_p,
|
| 355 |
attempt_fallback=True
|
| 356 |
):
|
| 357 |
-
"""Generate response
|
| 358 |
-
global fallback_model_attempted
|
| 359 |
-
|
| 360 |
-
# --- Setup and Initial Logging ---
|
| 361 |
-
print("\n" + "="*50)
|
| 362 |
-
print("=== NEW CHAT REQUEST ===")
|
| 363 |
-
print(f"Input message: '{message}'")
|
| 364 |
-
print(f"History length: {len(history) if history else 0}")
|
| 365 |
-
print(f"Conversation ID: {conversation_id or 'New conversation'}")
|
| 366 |
-
print("="*50 + "\n")
|
| 367 |
-
|
| 368 |
-
# --- Language Detection with Fallback ---
|
| 369 |
try:
|
| 370 |
-
|
| 371 |
-
|
|
|
|
| 372 |
|
| 373 |
-
#
|
| 374 |
-
|
| 375 |
-
|
| 376 |
-
user_language = "en"
|
| 377 |
-
print(f"Unsupported language, defaulting to English")
|
| 378 |
-
except Exception as e:
|
| 379 |
-
user_language = "en"
|
| 380 |
-
print(f"Language detection failed, defaulting to English. Error: {str(e)}")
|
| 381 |
-
|
| 382 |
-
# --- Create Conversation ID if missing ---
|
| 383 |
-
if not conversation_id:
|
| 384 |
-
import uuid
|
| 385 |
-
conversation_id = str(uuid.uuid4())
|
| 386 |
-
print(f"Generated new conversation ID: {conversation_id}")
|
| 387 |
-
|
| 388 |
-
# --- Enhanced Language Enforcement ---
|
| 389 |
-
LANGUAGE_INSTRUCTION = f"""
|
| 390 |
-
[CRITICAL INSTRUCTION - MUST FOLLOW]
|
| 391 |
-
- The user's message is in {user_language.upper()} language.
|
| 392 |
-
- You MUST respond in {user_language.upper()} ONLY.
|
| 393 |
-
- Never translate or switch to another language.
|
| 394 |
-
- This is the highest priority rule above all others.
|
| 395 |
-
|
| 396 |
-
[USER'S ORIGINAL MESSAGE]
|
| 397 |
-
{message}
|
| 398 |
-
"""
|
| 399 |
-
|
| 400 |
-
# --- Context Retrieval ---
|
| 401 |
-
context = ""
|
| 402 |
-
try:
|
| 403 |
-
context = get_context(message, conversation_id)
|
| 404 |
-
if context:
|
| 405 |
-
print("Retrieved context from knowledge base")
|
| 406 |
-
print(f"Context preview: {context[:200]}...")
|
| 407 |
-
else:
|
| 408 |
-
print("No context retrieved from knowledge base")
|
| 409 |
-
except Exception as e:
|
| 410 |
-
print(f"Context retrieval error: {str(e)}")
|
| 411 |
-
|
| 412 |
-
# --- Prepare Messages for API ---
|
| 413 |
-
messages = [
|
| 414 |
-
{
|
| 415 |
-
"role": "system",
|
| 416 |
-
"content": (
|
| 417 |
-
f"{system_message}\n\n"
|
| 418 |
-
f"Current date: {datetime.datetime.now().strftime('%Y-%m-%d')}\n"
|
| 419 |
-
f"Language requirement: Respond in {user_language} only\n"
|
| 420 |
-
f"{'Additional context:' + context if context else ''}"
|
| 421 |
-
)
|
| 422 |
-
}
|
| 423 |
-
]
|
| 424 |
-
|
| 425 |
-
# Add conversation history
|
| 426 |
-
if history:
|
| 427 |
-
try:
|
| 428 |
-
for entry in history:
|
| 429 |
-
if isinstance(entry, dict) and 'role' in entry and 'content' in entry:
|
| 430 |
-
messages.append(entry)
|
| 431 |
-
print(f"Added {len(history)} history messages")
|
| 432 |
-
except Exception as e:
|
| 433 |
-
print(f"Error processing history: {str(e)}")
|
| 434 |
-
|
| 435 |
-
# Add current message with language enforcement
|
| 436 |
-
messages.append({
|
| 437 |
-
"role": "user",
|
| 438 |
-
"content": LANGUAGE_INSTRUCTION
|
| 439 |
-
})
|
| 440 |
-
|
| 441 |
-
# --- API Request with Error Handling ---
|
| 442 |
-
try:
|
| 443 |
-
print("\nSending request to model API...")
|
| 444 |
-
print(f"Model: {ACTIVE_MODEL['id']}")
|
| 445 |
-
print(f"Parameters: temp={temperature}, top_p={top_p}, max_tokens={max_tokens}")
|
| 446 |
|
| 447 |
-
#
|
| 448 |
response = client.chat_completion(
|
| 449 |
-
messages=
|
|
|
|
|
|
|
|
|
|
|
|
|
| 450 |
max_tokens=max_tokens,
|
| 451 |
temperature=temperature,
|
| 452 |
top_p=top_p,
|
| 453 |
stream=False
|
| 454 |
)
|
| 455 |
|
| 456 |
-
# Extract and validate response
|
| 457 |
-
if not response.choices:
|
| 458 |
-
raise ValueError("Empty response from API")
|
| 459 |
-
|
| 460 |
bot_response = response.choices[0].message.content
|
| 461 |
-
print(f"\nRaw API response: {bot_response}")
|
| 462 |
|
| 463 |
-
#
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
if response_lang != user_language:
|
| 467 |
-
print(f"WARNING: Response language mismatch! Expected {user_language}, got {response_lang}")
|
| 468 |
-
# Add language correction prefix if mismatch
|
| 469 |
-
bot_response = f"[Language corrected to {user_language}]\n{bot_response}"
|
| 470 |
-
except Exception as e:
|
| 471 |
-
print(f"Couldn't verify response language: {str(e)}")
|
| 472 |
-
|
| 473 |
-
# --- Format Final Output ---
|
| 474 |
-
new_history = history.copy() if history else []
|
| 475 |
-
new_history.extend([
|
| 476 |
{"role": "user", "content": message},
|
| 477 |
{"role": "assistant", "content": bot_response}
|
| 478 |
-
]
|
| 479 |
|
| 480 |
-
# Reset fallback flag on success
|
| 481 |
-
fallback_model_attempted = False
|
| 482 |
-
|
| 483 |
-
print("\n=== SUCCESSFUL RESPONSE ===")
|
| 484 |
return new_history, conversation_id
|
| 485 |
|
| 486 |
except Exception as e:
|
| 487 |
-
|
| 488 |
-
|
| 489 |
|
| 490 |
-
# ---
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
if fallback_model_key:
|
| 494 |
-
print(f"Attempting fallback to {fallback_model_key}")
|
| 495 |
-
fallback_model_attempted = True
|
| 496 |
-
|
| 497 |
-
# Switch model temporarily
|
| 498 |
-
original_model = ACTIVE_MODEL.copy()
|
| 499 |
-
if switch_to_model(fallback_model_key):
|
| 500 |
-
try:
|
| 501 |
-
result = yield from respond(
|
| 502 |
-
message, history, conversation_id,
|
| 503 |
-
system_message, max_tokens,
|
| 504 |
-
temperature, top_p,
|
| 505 |
-
attempt_fallback=False # Don't recurse infinitely
|
| 506 |
-
)
|
| 507 |
-
# Restore original model
|
| 508 |
-
ACTIVE_MODEL.update(original_model)
|
| 509 |
-
initialize_client(ACTIVE_MODEL['id'])
|
| 510 |
-
return result
|
| 511 |
-
except Exception as fallback_e:
|
| 512 |
-
print(f"Fallback also failed: {str(fallback_e)}")
|
| 513 |
-
|
| 514 |
-
# --- Error Response Formatting ---
|
| 515 |
-
friendly_error = format_friendly_error(error_msg)
|
| 516 |
-
print(f"Returning error to user: {friendly_error}")
|
| 517 |
-
|
| 518 |
-
error_history = history.copy() if history else []
|
| 519 |
-
error_history.extend([
|
| 520 |
{"role": "user", "content": message},
|
| 521 |
-
{"role": "assistant", "content":
|
| 522 |
-
]
|
| 523 |
|
| 524 |
return error_history, conversation_id
|
| 525 |
|
| 526 |
-
|
| 527 |
def format_friendly_error(api_error):
|
| 528 |
"""Convert API errors to user-friendly messages"""
|
| 529 |
if "402" in api_error or "Payment Required" in api_error:
|
|
@@ -619,7 +496,7 @@ def save_chat_history(history, conversation_id):
|
|
| 619 |
# Initialize the Hugging Face API client
|
| 620 |
api = HfApi(token=HF_TOKEN)
|
| 621 |
|
| 622 |
-
|
| 623 |
dir_name = os.path.basename(CHAT_HISTORY_PATH)
|
| 624 |
target_path = f"{dir_name}/{filename}"
|
| 625 |
|
|
@@ -643,39 +520,41 @@ def save_chat_history(history, conversation_id):
|
|
| 643 |
return False
|
| 644 |
|
| 645 |
def respond_and_clear(message, history, conversation_id):
|
| 646 |
-
"""
|
| 647 |
try:
|
| 648 |
-
# Get model parameters
|
| 649 |
-
|
| 650 |
-
temperature = ACTIVE_MODEL['parameters']['temperature']
|
| 651 |
-
top_p = ACTIVE_MODEL['parameters']['top_p']
|
| 652 |
|
| 653 |
-
#
|
| 654 |
-
|
| 655 |
message=message,
|
| 656 |
history=history if history else [],
|
| 657 |
conversation_id=conversation_id,
|
| 658 |
system_message=DEFAULT_SYSTEM_MESSAGE,
|
| 659 |
-
max_tokens=
|
| 660 |
-
temperature=temperature,
|
| 661 |
-
top_p=top_p
|
| 662 |
-
)
|
| 663 |
-
if isinstance(response, tuple) and len(response) == 2:
|
| 664 |
-
new_history, conv_id = response
|
| 665 |
-
return new_history, conv_id, ""
|
| 666 |
|
| 667 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 668 |
|
| 669 |
except Exception as e:
|
| 670 |
print(f"Error in respond_and_clear: {str(e)}")
|
| 671 |
|
| 672 |
-
# Create error
|
| 673 |
-
error_history =
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
"role": "assistant",
|
| 677 |
-
|
| 678 |
-
})
|
| 679 |
|
| 680 |
return error_history, conversation_id, ""
|
| 681 |
|
|
|
|
| 343 |
except Exception as e:
|
| 344 |
print(f"Language detection error: {str(e)}. Defaulting to English.")
|
| 345 |
return "en"
|
| 346 |
+
|
| 347 |
def respond(
|
| 348 |
message,
|
| 349 |
history,
|
|
|
|
| 354 |
top_p,
|
| 355 |
attempt_fallback=True
|
| 356 |
):
|
| 357 |
+
"""Generate response with proper error handling"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 358 |
try:
|
| 359 |
+
# Initialize response variables
|
| 360 |
+
bot_response = ""
|
| 361 |
+
error_occurred = False
|
| 362 |
|
| 363 |
+
# --- Language Detection ---
|
| 364 |
+
user_language = language_processor.detect_language(message)
|
| 365 |
+
lang_instruction = language_processor.get_language_instruction(user_language, message)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 366 |
|
| 367 |
+
# --- API Request ---
|
| 368 |
response = client.chat_completion(
|
| 369 |
+
messages=[
|
| 370 |
+
{"role": "system", "content": system_message},
|
| 371 |
+
*history,
|
| 372 |
+
{"role": "user", "content": lang_instruction}
|
| 373 |
+
],
|
| 374 |
max_tokens=max_tokens,
|
| 375 |
temperature=temperature,
|
| 376 |
top_p=top_p,
|
| 377 |
stream=False
|
| 378 |
)
|
| 379 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 380 |
bot_response = response.choices[0].message.content
|
|
|
|
| 381 |
|
| 382 |
+
# --- Format Successful Response ---
|
| 383 |
+
new_history = [
|
| 384 |
+
*history,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 385 |
{"role": "user", "content": message},
|
| 386 |
{"role": "assistant", "content": bot_response}
|
| 387 |
+
]
|
| 388 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
return new_history, conversation_id
|
| 390 |
|
| 391 |
except Exception as e:
|
| 392 |
+
print(f"API Error: {str(e)}")
|
| 393 |
+
error_msg = format_friendly_error(str(e))
|
| 394 |
|
| 395 |
+
# --- Format Error Response ---
|
| 396 |
+
error_history = [
|
| 397 |
+
*history,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 398 |
{"role": "user", "content": message},
|
| 399 |
+
{"role": "assistant", "content": error_msg}
|
| 400 |
+
]
|
| 401 |
|
| 402 |
return error_history, conversation_id
|
| 403 |
|
|
|
|
| 404 |
def format_friendly_error(api_error):
|
| 405 |
"""Convert API errors to user-friendly messages"""
|
| 406 |
if "402" in api_error or "Payment Required" in api_error:
|
|
|
|
| 496 |
# Initialize the Hugging Face API client
|
| 497 |
api = HfApi(token=HF_TOKEN)
|
| 498 |
|
| 499 |
+
# Extract just the directory name from CHAT_HISTORY_PATH
|
| 500 |
dir_name = os.path.basename(CHAT_HISTORY_PATH)
|
| 501 |
target_path = f"{dir_name}/{filename}"
|
| 502 |
|
|
|
|
| 520 |
return False
|
| 521 |
|
| 522 |
def respond_and_clear(message, history, conversation_id):
|
| 523 |
+
"""Wrapper function with proper output handling"""
|
| 524 |
try:
|
| 525 |
+
# Get current model parameters
|
| 526 |
+
params = ACTIVE_MODEL['parameters']
|
|
|
|
|
|
|
| 527 |
|
| 528 |
+
# Call respond function
|
| 529 |
+
result = respond(
|
| 530 |
message=message,
|
| 531 |
history=history if history else [],
|
| 532 |
conversation_id=conversation_id,
|
| 533 |
system_message=DEFAULT_SYSTEM_MESSAGE,
|
| 534 |
+
max_tokens=params['max_length'],
|
| 535 |
+
temperature=params['temperature'],
|
| 536 |
+
top_p=params['top_p']
|
| 537 |
+
)
|
|
|
|
|
|
|
|
|
|
| 538 |
|
| 539 |
+
if not result:
|
| 540 |
+
raise ValueError("Empty response from API")
|
| 541 |
+
|
| 542 |
+
new_history, new_conv_id = result
|
| 543 |
+
|
| 544 |
+
# Save chat history
|
| 545 |
+
save_chat_history(new_history, new_conv_id)
|
| 546 |
+
|
| 547 |
+
return new_history, new_conv_id, "" # Clear input
|
| 548 |
|
| 549 |
except Exception as e:
|
| 550 |
print(f"Error in respond_and_clear: {str(e)}")
|
| 551 |
|
| 552 |
+
# Create safe error response
|
| 553 |
+
error_history = [
|
| 554 |
+
*history,
|
| 555 |
+
{"role": "user", "content": message},
|
| 556 |
+
{"role": "assistant", "content": "⚠️ An error occurred while processing the message. Please try again."}
|
| 557 |
+
]
|
|
|
|
| 558 |
|
| 559 |
return error_history, conversation_id, ""
|
| 560 |
|