Skip to content

Commit e52a664

Browse files
authored
Merge pull request #183 from yjg30737/feature/general
v1.6.1
2 parents 753459f + 5363731 commit e52a664

17 files changed

+213
-81
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "pyqt-openai"
7-
version = "1.6.0"
7+
version = "1.6.1"
88
description = "Python multipurpose chatbot that user can use GPT, other AI models altogether (Release Name: VividNode)"
99
authors = [{ name = "Jung Gyu Yoon", email = "yjg30737@gmail.com" }]
1010
license = { text = "MIT" }

pyqt_openai/__init__.py

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
# For the sake of following the PEP8 standard, we will declare module-level dunder names.
2424
# PEP8 standard about dunder names: https://peps.python.org/pep-0008/#module-level-dunder-names
2525

26-
__version__ = "1.6.0"
26+
__version__ = "1.6.1"
2727
__author__ = "Jung Gyu Yoon"
2828

2929
# Constants
@@ -79,11 +79,9 @@ def get_config_directory():
7979
BIN_DIR = get_config_directory()
8080

8181
UPDATER_NAME = "Updater.exe" if sys.platform == "win32" else "Updater"
82-
EDGE_TTS_NAME = "edge-tts.exe" if sys.platform == "win32" else "edge-tts"
8382

8483
# The default updater path (relative to the application's root directory) - For Windows
8584
UPDATER_PATH = os.path.join(BIN_DIR, UPDATER_NAME)
86-
EDGE_TTS_PATH = os.path.join(BIN_DIR, EDGE_TTS_NAME)
8785

8886
# Move the binary file to the config folder to prevent "file not found" error
8987
def move_bin(filename, dst_dir):
@@ -94,7 +92,6 @@ def move_bin(filename, dst_dir):
9492
shutil.move(original_path, dst_dir)
9593

9694
move_bin(UPDATER_NAME, UPDATER_PATH)
97-
move_bin(EDGE_TTS_NAME, EDGE_TTS_PATH)
9895

9996
CONTACT = "yjg30737@gmail.com"
10097
APP_INITIAL_WINDOW_SIZE = (1280, 768)
@@ -205,6 +202,7 @@ def move_bin(filename, dst_dir):
205202
ICON_PATREON = os.path.join(ICON_PATH, "patreon.svg")
206203
ICON_SHORTCUT = os.path.join(ICON_PATH, "shortcut.svg")
207204
ICON_REALTIME_API = os.path.join(ICON_PATH, "realtime_api.svg")
205+
ICON_FILE = os.path.join(ICON_PATH, "file.svg")
208206

209207
## CUSTOMIZE
210208
DEFAULT_ICON_SIZE = (24, 24)
@@ -213,6 +211,7 @@ def move_bin(filename, dst_dir):
213211
DEFAULT_FONT_SIZE = 12
214212
DEFAULT_FONT_FAMILY = "Arial"
215213

214+
DEFAULT_HIGHLIGHT_TEXT_COLOR = "#A2D0DD"
216215
DEFAULT_BUTTON_HOVER_COLOR = "#A2D0DD"
217216
DEFAULT_BUTTON_PRESSED_COLOR = "#B3E0FF"
218217
DEFAULT_BUTTON_CHECKED_COLOR = "#B3E0FF"
@@ -240,26 +239,37 @@ def move_bin(filename, dst_dir):
240239
# DEFAULT_MARKDOWN_h6_color = '#000'
241240
# DEFAULT_MARKDOWN_a_color = '#000'
242241

242+
243+
244+
command_key = "Ctrl"
245+
if sys.platform == "darwin":
246+
command_key = "Cmd"
247+
248+
243249
## SHORTCUT
244250
DEFAULT_SHORTCUT_GENERAL_ACTION = "Return"
245-
DEFAULT_SHORTCUT_FIND_PREV = "Ctrl+Shift+D"
246-
DEFAULT_SHORTCUT_FIND_NEXT = "Ctrl+D"
251+
DEFAULT_SHORTCUT_FIND_PREV = f"{command_key}+Shift+D"
252+
DEFAULT_SHORTCUT_FIND_NEXT = f"{command_key}+D"
247253
DEFAULT_SHORTCUT_FIND_CLOSE = "Escape"
248-
DEFAULT_SHORTCUT_PROMPT_BEGINNING = "Ctrl+B"
249-
DEFAULT_SHORTCUT_PROMPT_ENDING = "Ctrl+E"
250-
DEFAULT_SHORTCUT_SUPPORT_PROMPT_COMMAND = "Ctrl+Shift+P"
251-
DEFAULT_SHORTCUT_STACK_ON_TOP = "Ctrl+Shift+S"
252-
DEFAULT_SHORTCUT_SHOW_SECONDARY_TOOLBAR = "Ctrl+Shift+T"
254+
DEFAULT_SHORTCUT_PROMPT_BEGINNING = f"{command_key}+B"
255+
DEFAULT_SHORTCUT_PROMPT_ENDING = f"{command_key}+E"
256+
DEFAULT_SHORTCUT_SUPPORT_PROMPT_COMMAND = f"{command_key}+Shift+P"
257+
DEFAULT_SHORTCUT_STACK_ON_TOP = f"{command_key}+Shift+S"
258+
DEFAULT_SHORTCUT_SHOW_SECONDARY_TOOLBAR = f"{command_key}+Shift+T"
253259
DEFAULT_SHORTCUT_FOCUS_MODE = "F10"
254260
DEFAULT_SHORTCUT_FULL_SCREEN = "F11"
255-
DEFAULT_SHORTCUT_FIND = "Ctrl+F"
256-
DEFAULT_SHORTCUT_JSON_MODE = "Ctrl+J"
257-
DEFAULT_SHORTCUT_LEFT_SIDEBAR_WINDOW = "Ctrl+L"
258-
DEFAULT_SHORTCUT_RIGHT_SIDEBAR_WINDOW = "Ctrl+R"
259-
DEFAULT_SHORTCUT_CONTROL_PROMPT_WINDOW = "Ctrl+Shift+C"
260-
DEFAULT_SHORTCUT_RECORD = "Ctrl+Shift+R"
261-
DEFAULT_SHORTCUT_SETTING = "Ctrl+Alt+S"
262-
DEFAULT_SHORTCUT_SEND = "Ctrl+Return"
261+
DEFAULT_SHORTCUT_FIND = f"{command_key}+F"
262+
DEFAULT_SHORTCUT_JSON_MODE = f"{command_key}+J"
263+
DEFAULT_SHORTCUT_LEFT_SIDEBAR_WINDOW = f"{command_key}+L"
264+
DEFAULT_SHORTCUT_RIGHT_SIDEBAR_WINDOW = f"{command_key}+R"
265+
DEFAULT_SHORTCUT_CONTROL_PROMPT_WINDOW = f"{command_key}+Shift+C"
266+
DEFAULT_SHORTCUT_RECORD = f"{command_key}+Shift+R"
267+
DEFAULT_SHORTCUT_SETTING = f"{command_key}+Alt+S"
268+
DEFAULT_SHORTCUT_SEND = f"{command_key}+Return"
269+
270+
DEFAULT_SWITCH_PROMPT_UP = f"{command_key}+Up"
271+
DEFAULT_SWITCH_PROMPT_DOWN = f"{command_key}+Down"
272+
263273

264274
## DIRECTORY PATH & FILE'S NAME
265275
MAIN_INDEX = "main.py"
@@ -303,6 +313,8 @@ def move_bin(filename, dst_dir):
303313
THREAD_TRIGGER_NAME_OLD = "conv_tr"
304314
MESSAGE_TABLE_NAME_OLD = "conv_unit_tb"
305315

316+
CHAT_FILE_TABLE_NAME = "chat_file_tb"
317+
306318
THREAD_TABLE_NAME = "thread_tb"
307319
THREAD_TRIGGER_NAME = "thread_tr"
308320
MESSAGE_TABLE_NAME = "message_tb"
@@ -336,6 +348,7 @@ def move_bin(filename, dst_dir):
336348
PROMPT_GROUP_TABLE_NAME = "prompt_group_tb"
337349
PROMPT_ENTRY_TABLE_NAME = "prompt_entry_tb"
338350

351+
339352
# AI
340353
## OPENAI
341354
OPENAI_REQUEST_URL = "https://api.openai.com/v1/models"
@@ -418,7 +431,13 @@ def move_bin(filename, dst_dir):
418431
{"display_name": "OpenAI", "env_var_name": "OPENAI_API_KEY", "api_key": ""},
419432
{"display_name": "Gemini", "env_var_name": "GEMINI_API_KEY", "api_key": ""},
420433
{"display_name": "Claude", "env_var_name": "CLAUDE_API_KEY", "api_key": ""},
421-
{"display_name": "Llama", "env_var_name": "LLAMA_API_KEY", "api_key": ""},
434+
435+
# For G4F only
436+
{"display_name": "DeepInfra", "env_var_name": "DEEPINFRA_API_KEY", "api_key": ""},
437+
{"display_name": "Groq", "env_var_name": "GROQ_API_KEY", "api_key": ""},
438+
{"display_name": "HuggingFace", "env_var_name": "HUGGINGFACE_API_KEY", "api_key": ""},
439+
{"display_name": "OpenRouter", "env_var_name": "OPENROUTER_API_KEY", "api_key": ""},
440+
{"display_name": "Perplexity API", "env_var_name": "PERPLEXITY_API_KEY", "api_key": ""}
422441
]
423442

424443
# This has to be managed separately since some of the arguments are different with usual models
@@ -436,8 +455,7 @@ def move_bin(filename, dst_dir):
436455
PROVIDER_MODEL_DICT = {
437456
"OpenAI": ["gpt-4o", "gpt-4o-mini"] + O1_MODELS,
438457
"Gemini": ["gemini-1.5-flash", "gemini-1.5-pro"],
439-
"Claude": ["claude-3-5-sonnet-20240620"],
440-
"Llama": ["llama3-70b"],
458+
"Claude": ["claude-3-5-sonnet-20240620"]
441459
}
442460

443461
# Constants related to the number of messages LLM will store
@@ -633,24 +651,25 @@ def move_bin(filename, dst_dir):
633651
# ----------------------------
634652
CONFIG_DATA = {
635653
"General": {
636-
"TAB_IDX": 0,
654+
# Language
637655
"lang": "English",
638-
"show_chat_list": True,
639-
"stream": True,
656+
# DB
640657
"db": "conv",
641-
"model": DEFAULT_LLM,
658+
# GUI & Application settings
659+
"TAB_IDX": 0,
660+
"show_chat_list": True,
642661
"show_setting": True,
643-
"use_llama_index": False,
644662
"do_not_ask_again": False,
645663
"show_prompt": True,
646-
"system": "You are a helpful assistant.",
647664
"notify_finish": True,
648-
"temperature": 1,
649-
"max_tokens": -1,
650665
"show_secondary_toolbar": True,
651-
"top_p": 1,
666+
"focus_mode": False,
667+
"show_as_markdown": True,
668+
"show_realtime_api": False,
669+
"run_at_startup": True,
670+
"manual_update": True,
671+
# Columns
652672
"chat_column_to_show": ["id", "name", "insert_dt", "update_dt"],
653-
"frequency_penalty": 0,
654673
"image_column_to_show": [
655674
"id",
656675
"model",
@@ -666,25 +685,28 @@ def move_bin(filename, dst_dir):
666685
"update_dt",
667686
"insert_dt",
668687
],
688+
# Parameters
689+
"model": DEFAULT_LLM,
690+
"system": "You are a helpful assistant.",
691+
"stream": True,
692+
"temperature": 1,
693+
"max_tokens": -1,
694+
"top_p": 1,
695+
"frequency_penalty": 0,
669696
"presence_penalty": 0,
670697
"json_object": False,
671698
"maximum_messages_in_parameter": MAXIMUM_MESSAGES_IN_PARAMETER,
672-
"show_as_markdown": True,
673-
"run_at_startup": True,
674699
"use_max_tokens": False,
700+
# Llama Index
701+
"use_llama_index": False,
702+
"llama_index_directory": "",
703+
# Customize
675704
"background_image": "",
676705
"user_image": DEFAULT_USER_IMAGE_PATH,
677706
"ai_image": DEFAULT_AI_IMAGE_PATH,
678707
"font_size": DEFAULT_FONT_SIZE,
679708
"font_family": DEFAULT_FONT_FAMILY,
680-
"llama_index_directory": "",
681709
"apply_user_defined_styles": False,
682-
"focus_mode": False,
683-
"OPENAI_API_KEY": "",
684-
"GEMINI_API_KEY": "",
685-
"CLAUDE_API_KEY": "",
686-
"LLAMA_API_KEY": "",
687-
"show_realtime_api": False,
688710
# G4F
689711
"g4f_model": DEFAULT_LLM,
690712
"provider": G4F_PROVIDER_DEFAULT,
@@ -747,13 +769,11 @@ def move_bin(filename, dst_dir):
747769
},
748770
}
749771

750-
751772
# Dynamically add the API keys to the configuration data
752773
def update_general_config_with_api_keys(config_data, api_configs):
753774
for config in api_configs:
754775
config_data["General"][config["env_var_name"]] = config["api_key"]
755776

756-
757777
update_general_config_with_api_keys(CONFIG_DATA, DEFAULT_API_CONFIGS)
758778

759779
# Set the default llama index cache directory for preventing any issues such as PermissionError

pyqt_openai/chat_widget/center/aiChatUnit.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
ICON_INFO,
77
ICON_FAVORITE_YES,
88
ICON_SPEAKER,
9-
WHISPER_TTS_MODEL,
9+
WHISPER_TTS_MODEL, ICON_FILE,
1010
)
1111
from pyqt_openai.config_loader import CONFIG_MANAGER
1212
from pyqt_openai.chat_widget.center.chatUnit import ChatUnit
@@ -15,6 +15,7 @@
1515
from pyqt_openai.globals import DB
1616
from pyqt_openai.util.script import stream_to_speakers
1717
from pyqt_openai.widgets.button import Button
18+
from pyqt_openai.widgets.fileTableDialog import FileTableDialog
1819

1920

2021
class AIChatUnit(ChatUnit):
@@ -39,15 +40,19 @@ def __initAIChatUi(self):
3940
self.__infoBtn.setStyleAndIcon(ICON_INFO)
4041
self.__infoBtn.clicked.connect(self.__showResponseInfoDialog)
4142

43+
self.__fileListBtn = Button()
44+
self.__fileListBtn.setStyleAndIcon(ICON_FILE)
45+
self.__fileListBtn.clicked.connect(self.__showFileListDialog)
46+
4247
self.__speakerBtn = Button()
4348
self.__speakerBtn.setStyleAndIcon(ICON_SPEAKER)
4449
self.__speakerBtn.setCheckable(True)
4550
self.__speakerBtn.toggled.connect(self.__speak)
4651
self.thread = None
4752

48-
self.getMenuWidget().layout().insertWidget(2, self.__favoriteBtn)
49-
self.getMenuWidget().layout().insertWidget(3, self.__infoBtn)
50-
self.getMenuWidget().layout().insertWidget(4, self.__speakerBtn)
53+
self.getMenuWidget().layout().insertWidget(3, self.__favoriteBtn)
54+
self.getMenuWidget().layout().insertWidget(4, self.__infoBtn)
55+
self.getMenuWidget().layout().insertWidget(5, self.__speakerBtn)
5156

5257
self.setBackgroundRole(QPalette.ColorRole.AlternateBase)
5358
self.setAutoFillBackground(True)
@@ -68,9 +73,15 @@ def __showResponseInfoDialog(self):
6873
dialog = ResponseInfoDialog(self.__result_info, parent=self)
6974
dialog.exec()
7075

76+
def __showFileListDialog(self):
77+
if self.__result_info:
78+
dialog = FileTableDialog(self.__result_info, parent=self)
79+
dialog.exec()
80+
7181
def afterResponse(self, arg):
7282
self.toggleGUI(True)
7383
self.__result_info = arg
84+
self._nameLbl.setText(arg.model)
7485
self.__favorite(True if arg.favorite else False, insert_f=False)
7586

7687
if arg.is_json_response_available:
@@ -85,10 +96,6 @@ def toggleGUI(self, f: bool):
8596
self.__infoBtn.setEnabled(f)
8697
self.__speakerBtn.setEnabled(f)
8798

88-
def __setResponseInfo(self, arg: ChatMessageContainer):
89-
self.__result_info = arg
90-
self.__favorite(True if arg.favorite else False, insert_f=False)
91-
9299
def getResponseInfo(self):
93100
"""
94101
Get the response information

pyqt_openai/chat_widget/center/chatHome.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
DEFAULT_APP_NAME,
99
HOW_TO_GET_OPENAI_API_KEY_URL,
1010
LARGE_LABEL_PARAM,
11-
MEDIUM_LABEL_PARAM,
11+
MEDIUM_LABEL_PARAM, QUICKSTART_MANUAL_URL,
1212
)
1313
from pyqt_openai.lang.translations import LangClass
1414
from pyqt_openai.widgets.linkLabel import LinkLabel
@@ -30,7 +30,7 @@ def __initUi(self):
3030

3131
self.__quickStartManualLbl = LinkLabel()
3232
self.__quickStartManualLbl.setText(LangClass.TRANSLATIONS["Quick Start Manual"])
33-
self.__quickStartManualLbl.setUrl(HOW_TO_GET_OPENAI_API_KEY_URL)
33+
self.__quickStartManualLbl.setUrl(QUICKSTART_MANUAL_URL)
3434
self.__quickStartManualLbl.setFont(QFont(*MEDIUM_LABEL_PARAM))
3535
self.__quickStartManualLbl.setAlignment(Qt.AlignmentFlag.AlignCenter)
3636

pyqt_openai/chat_widget/center/chatUnit.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
QVBoxLayout,
77
QHBoxLayout,
88
QSpacerItem,
9-
QSizePolicy,
9+
QSizePolicy, QLabel,
1010
)
1111

1212
from pyqt_openai import DEFAULT_ICON_SIZE, ICON_COPY
@@ -26,12 +26,16 @@ def __initUi(self):
2626

2727
self._icon = RoundedImage()
2828
self._icon.setMaximumSize(*DEFAULT_ICON_SIZE)
29+
self._icon.setStyleSheet('margin-right: 3px;')
30+
31+
self._nameLbl = QLabel()
2932

3033
self._copyBtn = Button()
3134
self._copyBtn.setStyleAndIcon(ICON_COPY)
3235
self._copyBtn.clicked.connect(self.__copy)
3336

3437
lay.addWidget(self._icon)
38+
lay.addWidget(self._nameLbl)
3539
lay.addSpacerItem(QSpacerItem(10, 10, QSizePolicy.Policy.MinimumExpanding))
3640
lay.addWidget(self._copyBtn)
3741
lay.setContentsMargins(2, 2, 2, 2)

pyqt_openai/ico/file.svg

Lines changed: 30 additions & 0 deletions
Loading

pyqt_openai/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ class SettingsParamsContainer(Container):
145145
show_as_markdown: bool = True
146146
apply_user_defined_styles: bool = False
147147
run_at_startup: bool = True
148+
manual_update: bool = True
148149

149150
voice_provider: str = TTS_DEFAULT_PROVIDER
150151
voice: str = TTS_DEFAULT_VOICE

0 commit comments

Comments
 (0)