AI_HUB2 / client_chat.py
DSDUDEd's picture
Update client_chat.py
1fd2ecb verified
import sys
import requests
import json
from PyQt6.QtWidgets import (
QApplication, QWidget, QVBoxLayout, QHBoxLayout,
QPushButton, QTextEdit, QLineEdit, QLabel, QComboBox
)
from PyQt6.QtCore import QTimer, Qt
from PyQt6.QtGui import QFont, QCursor, QIcon, QColor, QTextCursor
API_BASE = "http://127.0.0.1:7860/api"
class ChatClient(QWidget):
def __init__(self, token):
super().__init__()
self.token = token # Token comes from main.py login
self.ai_typing_timer = None
self.ai_text_buffer = ""
self.setWindowTitle("AI HUB Desktop Client")
self.setWindowIcon(QIcon("favicon.png"))
self.init_ui()
self.showMaximized()
self.setCursor(QCursor(Qt.CursorShape.ArrowCursor))
def init_ui(self):
self.layout = QVBoxLayout(self)
self.setLayout(self.layout)
# Chat Display Area
self.chat_area = QTextEdit()
self.chat_area.setReadOnly(True)
self.chat_area.setFont(QFont("Consolas", 12))
self.chat_area.setStyleSheet("""
QTextEdit {
background-color: #1e1e1e;
color: #f1f1f1;
border-radius: 10px;
padding: 10px;
}
""")
self.layout.addWidget(self.chat_area)
# Typing Indicator
self.typing_label = QLabel("")
self.typing_label.setStyleSheet("color: #00ff00; font-style: italic;")
self.layout.addWidget(self.typing_label)
# Input Area
input_layout = QHBoxLayout()
self.user_input = QLineEdit()
self.user_input.setPlaceholderText("Type your message here...")
self.user_input.returnPressed.connect(self.send_message)
self.user_input.setStyleSheet("""
QLineEdit {
border-radius: 8px;
padding: 6px;
font-size: 14px;
}
""")
input_layout.addWidget(self.user_input)
self.send_button = QPushButton("Send")
self.send_button.setStyleSheet("""
QPushButton {
background-color: #0078d7;
color: white;
border-radius: 8px;
padding: 6px 12px;
}
QPushButton:hover {
background-color: #005a9e;
}
""")
self.send_button.clicked.connect(self.send_message)
input_layout.addWidget(self.send_button)
# Model selection
self.model_select = QComboBox()
self.model_select.addItems(["qwen", "deepseek"])
self.model_select.setStyleSheet("""
QComboBox {
border-radius: 8px;
padding: 4px;
font-size: 14px;
}
""")
input_layout.addWidget(self.model_select)
self.layout.addLayout(input_layout)
# --------------------
# Display AI typing animation
# --------------------
def type_ai_message(self, full_text, delay=30):
self.ai_text_buffer = full_text
self.typing_label.setText("πŸ€– AI is typing...")
self.ai_typing_timer = QTimer()
self.ai_typing_timer.timeout.connect(self._type_next_char)
self.ai_typing_timer.start(delay)
def _type_next_char(self):
if self.ai_text_buffer:
char = self.ai_text_buffer[0]
self.chat_area.moveCursor(QTextCursor.MoveOperation.End)
self.chat_area.insertPlainText(char)
self.ai_text_buffer = self.ai_text_buffer[1:]
else:
self.ai_typing_timer.stop()
self.typing_label.setText("")
# --------------------
# Send message to backend
# --------------------
def send_message(self):
message = self.user_input.text().strip()
if not message:
return
self.chat_area.append(f"πŸ§‘ {message}")
self.user_input.clear()
self.typing_label.setText("πŸ€– AI is thinking...")
model_choice = self.model_select.currentText()
headers = {"Content-Type": "application/json", "Authorization": f"Bearer {self.token}"}
try:
res = requests.post(
f"{API_BASE}/chat",
headers=headers,
data=json.dumps({"message": message, "model": model_choice, "max_tokens": 200}),
timeout=30
)
data = res.json()
if "response" in data:
self.chat_area.append("πŸ€– ")
self.type_ai_message(data["response"])
else:
self.chat_area.append("Error: " + data.get("error", "Unknown error"))
except Exception as e:
self.chat_area.append(f"Error sending message: {e}")
# --------------------
# Run App
# --------------------
if __name__ == "__main__":
# Example: Pass token from main.py login
token = "YOUR_JWT_TOKEN_HERE"
app = QApplication(sys.argv)
window = ChatClient(token)
window.show()
sys.exit(app.exec())