Skip to content

Commit

Permalink
Merge pull request #184 from yjg30737/Dev
Browse files Browse the repository at this point in the history
v1.6.1
  • Loading branch information
yjg30737 authored Nov 5, 2024
2 parents 753459f + e52a664 commit cb4a6c8
Show file tree
Hide file tree
Showing 17 changed files with 213 additions and 81 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "pyqt-openai"
version = "1.6.0"
version = "1.6.1"
description = "Python multipurpose chatbot that user can use GPT, other AI models altogether (Release Name: VividNode)"
authors = [{ name = "Jung Gyu Yoon", email = "[email protected]" }]
license = { text = "MIT" }
Expand Down
106 changes: 63 additions & 43 deletions pyqt_openai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
# For the sake of following the PEP8 standard, we will declare module-level dunder names.
# PEP8 standard about dunder names: https://peps.python.org/pep-0008/#module-level-dunder-names

__version__ = "1.6.0"
__version__ = "1.6.1"
__author__ = "Jung Gyu Yoon"

# Constants
Expand Down Expand Up @@ -79,11 +79,9 @@ def get_config_directory():
BIN_DIR = get_config_directory()

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

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

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

move_bin(UPDATER_NAME, UPDATER_PATH)
move_bin(EDGE_TTS_NAME, EDGE_TTS_PATH)

CONTACT = "[email protected]"
APP_INITIAL_WINDOW_SIZE = (1280, 768)
Expand Down Expand Up @@ -205,6 +202,7 @@ def move_bin(filename, dst_dir):
ICON_PATREON = os.path.join(ICON_PATH, "patreon.svg")
ICON_SHORTCUT = os.path.join(ICON_PATH, "shortcut.svg")
ICON_REALTIME_API = os.path.join(ICON_PATH, "realtime_api.svg")
ICON_FILE = os.path.join(ICON_PATH, "file.svg")

## CUSTOMIZE
DEFAULT_ICON_SIZE = (24, 24)
Expand All @@ -213,6 +211,7 @@ def move_bin(filename, dst_dir):
DEFAULT_FONT_SIZE = 12
DEFAULT_FONT_FAMILY = "Arial"

DEFAULT_HIGHLIGHT_TEXT_COLOR = "#A2D0DD"
DEFAULT_BUTTON_HOVER_COLOR = "#A2D0DD"
DEFAULT_BUTTON_PRESSED_COLOR = "#B3E0FF"
DEFAULT_BUTTON_CHECKED_COLOR = "#B3E0FF"
Expand Down Expand Up @@ -240,26 +239,37 @@ def move_bin(filename, dst_dir):
# DEFAULT_MARKDOWN_h6_color = '#000'
# DEFAULT_MARKDOWN_a_color = '#000'



command_key = "Ctrl"
if sys.platform == "darwin":
command_key = "Cmd"


## SHORTCUT
DEFAULT_SHORTCUT_GENERAL_ACTION = "Return"
DEFAULT_SHORTCUT_FIND_PREV = "Ctrl+Shift+D"
DEFAULT_SHORTCUT_FIND_NEXT = "Ctrl+D"
DEFAULT_SHORTCUT_FIND_PREV = f"{command_key}+Shift+D"
DEFAULT_SHORTCUT_FIND_NEXT = f"{command_key}+D"
DEFAULT_SHORTCUT_FIND_CLOSE = "Escape"
DEFAULT_SHORTCUT_PROMPT_BEGINNING = "Ctrl+B"
DEFAULT_SHORTCUT_PROMPT_ENDING = "Ctrl+E"
DEFAULT_SHORTCUT_SUPPORT_PROMPT_COMMAND = "Ctrl+Shift+P"
DEFAULT_SHORTCUT_STACK_ON_TOP = "Ctrl+Shift+S"
DEFAULT_SHORTCUT_SHOW_SECONDARY_TOOLBAR = "Ctrl+Shift+T"
DEFAULT_SHORTCUT_PROMPT_BEGINNING = f"{command_key}+B"
DEFAULT_SHORTCUT_PROMPT_ENDING = f"{command_key}+E"
DEFAULT_SHORTCUT_SUPPORT_PROMPT_COMMAND = f"{command_key}+Shift+P"
DEFAULT_SHORTCUT_STACK_ON_TOP = f"{command_key}+Shift+S"
DEFAULT_SHORTCUT_SHOW_SECONDARY_TOOLBAR = f"{command_key}+Shift+T"
DEFAULT_SHORTCUT_FOCUS_MODE = "F10"
DEFAULT_SHORTCUT_FULL_SCREEN = "F11"
DEFAULT_SHORTCUT_FIND = "Ctrl+F"
DEFAULT_SHORTCUT_JSON_MODE = "Ctrl+J"
DEFAULT_SHORTCUT_LEFT_SIDEBAR_WINDOW = "Ctrl+L"
DEFAULT_SHORTCUT_RIGHT_SIDEBAR_WINDOW = "Ctrl+R"
DEFAULT_SHORTCUT_CONTROL_PROMPT_WINDOW = "Ctrl+Shift+C"
DEFAULT_SHORTCUT_RECORD = "Ctrl+Shift+R"
DEFAULT_SHORTCUT_SETTING = "Ctrl+Alt+S"
DEFAULT_SHORTCUT_SEND = "Ctrl+Return"
DEFAULT_SHORTCUT_FIND = f"{command_key}+F"
DEFAULT_SHORTCUT_JSON_MODE = f"{command_key}+J"
DEFAULT_SHORTCUT_LEFT_SIDEBAR_WINDOW = f"{command_key}+L"
DEFAULT_SHORTCUT_RIGHT_SIDEBAR_WINDOW = f"{command_key}+R"
DEFAULT_SHORTCUT_CONTROL_PROMPT_WINDOW = f"{command_key}+Shift+C"
DEFAULT_SHORTCUT_RECORD = f"{command_key}+Shift+R"
DEFAULT_SHORTCUT_SETTING = f"{command_key}+Alt+S"
DEFAULT_SHORTCUT_SEND = f"{command_key}+Return"

DEFAULT_SWITCH_PROMPT_UP = f"{command_key}+Up"
DEFAULT_SWITCH_PROMPT_DOWN = f"{command_key}+Down"


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

CHAT_FILE_TABLE_NAME = "chat_file_tb"

THREAD_TABLE_NAME = "thread_tb"
THREAD_TRIGGER_NAME = "thread_tr"
MESSAGE_TABLE_NAME = "message_tb"
Expand Down Expand Up @@ -336,6 +348,7 @@ def move_bin(filename, dst_dir):
PROMPT_GROUP_TABLE_NAME = "prompt_group_tb"
PROMPT_ENTRY_TABLE_NAME = "prompt_entry_tb"


# AI
## OPENAI
OPENAI_REQUEST_URL = "https://api.openai.com/v1/models"
Expand Down Expand Up @@ -418,7 +431,13 @@ def move_bin(filename, dst_dir):
{"display_name": "OpenAI", "env_var_name": "OPENAI_API_KEY", "api_key": ""},
{"display_name": "Gemini", "env_var_name": "GEMINI_API_KEY", "api_key": ""},
{"display_name": "Claude", "env_var_name": "CLAUDE_API_KEY", "api_key": ""},
{"display_name": "Llama", "env_var_name": "LLAMA_API_KEY", "api_key": ""},

# For G4F only
{"display_name": "DeepInfra", "env_var_name": "DEEPINFRA_API_KEY", "api_key": ""},
{"display_name": "Groq", "env_var_name": "GROQ_API_KEY", "api_key": ""},
{"display_name": "HuggingFace", "env_var_name": "HUGGINGFACE_API_KEY", "api_key": ""},
{"display_name": "OpenRouter", "env_var_name": "OPENROUTER_API_KEY", "api_key": ""},
{"display_name": "Perplexity API", "env_var_name": "PERPLEXITY_API_KEY", "api_key": ""}
]

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

# Constants related to the number of messages LLM will store
Expand Down Expand Up @@ -633,24 +651,25 @@ def move_bin(filename, dst_dir):
# ----------------------------
CONFIG_DATA = {
"General": {
"TAB_IDX": 0,
# Language
"lang": "English",
"show_chat_list": True,
"stream": True,
# DB
"db": "conv",
"model": DEFAULT_LLM,
# GUI & Application settings
"TAB_IDX": 0,
"show_chat_list": True,
"show_setting": True,
"use_llama_index": False,
"do_not_ask_again": False,
"show_prompt": True,
"system": "You are a helpful assistant.",
"notify_finish": True,
"temperature": 1,
"max_tokens": -1,
"show_secondary_toolbar": True,
"top_p": 1,
"focus_mode": False,
"show_as_markdown": True,
"show_realtime_api": False,
"run_at_startup": True,
"manual_update": True,
# Columns
"chat_column_to_show": ["id", "name", "insert_dt", "update_dt"],
"frequency_penalty": 0,
"image_column_to_show": [
"id",
"model",
Expand All @@ -666,25 +685,28 @@ def move_bin(filename, dst_dir):
"update_dt",
"insert_dt",
],
# Parameters
"model": DEFAULT_LLM,
"system": "You are a helpful assistant.",
"stream": True,
"temperature": 1,
"max_tokens": -1,
"top_p": 1,
"frequency_penalty": 0,
"presence_penalty": 0,
"json_object": False,
"maximum_messages_in_parameter": MAXIMUM_MESSAGES_IN_PARAMETER,
"show_as_markdown": True,
"run_at_startup": True,
"use_max_tokens": False,
# Llama Index
"use_llama_index": False,
"llama_index_directory": "",
# Customize
"background_image": "",
"user_image": DEFAULT_USER_IMAGE_PATH,
"ai_image": DEFAULT_AI_IMAGE_PATH,
"font_size": DEFAULT_FONT_SIZE,
"font_family": DEFAULT_FONT_FAMILY,
"llama_index_directory": "",
"apply_user_defined_styles": False,
"focus_mode": False,
"OPENAI_API_KEY": "",
"GEMINI_API_KEY": "",
"CLAUDE_API_KEY": "",
"LLAMA_API_KEY": "",
"show_realtime_api": False,
# G4F
"g4f_model": DEFAULT_LLM,
"provider": G4F_PROVIDER_DEFAULT,
Expand Down Expand Up @@ -747,13 +769,11 @@ def move_bin(filename, dst_dir):
},
}


# Dynamically add the API keys to the configuration data
def update_general_config_with_api_keys(config_data, api_configs):
for config in api_configs:
config_data["General"][config["env_var_name"]] = config["api_key"]


update_general_config_with_api_keys(CONFIG_DATA, DEFAULT_API_CONFIGS)

# Set the default llama index cache directory for preventing any issues such as PermissionError
Expand Down
23 changes: 15 additions & 8 deletions pyqt_openai/chat_widget/center/aiChatUnit.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
ICON_INFO,
ICON_FAVORITE_YES,
ICON_SPEAKER,
WHISPER_TTS_MODEL,
WHISPER_TTS_MODEL, ICON_FILE,
)
from pyqt_openai.config_loader import CONFIG_MANAGER
from pyqt_openai.chat_widget.center.chatUnit import ChatUnit
Expand All @@ -15,6 +15,7 @@
from pyqt_openai.globals import DB
from pyqt_openai.util.script import stream_to_speakers
from pyqt_openai.widgets.button import Button
from pyqt_openai.widgets.fileTableDialog import FileTableDialog


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

self.__fileListBtn = Button()
self.__fileListBtn.setStyleAndIcon(ICON_FILE)
self.__fileListBtn.clicked.connect(self.__showFileListDialog)

self.__speakerBtn = Button()
self.__speakerBtn.setStyleAndIcon(ICON_SPEAKER)
self.__speakerBtn.setCheckable(True)
self.__speakerBtn.toggled.connect(self.__speak)
self.thread = None

self.getMenuWidget().layout().insertWidget(2, self.__favoriteBtn)
self.getMenuWidget().layout().insertWidget(3, self.__infoBtn)
self.getMenuWidget().layout().insertWidget(4, self.__speakerBtn)
self.getMenuWidget().layout().insertWidget(3, self.__favoriteBtn)
self.getMenuWidget().layout().insertWidget(4, self.__infoBtn)
self.getMenuWidget().layout().insertWidget(5, self.__speakerBtn)

self.setBackgroundRole(QPalette.ColorRole.AlternateBase)
self.setAutoFillBackground(True)
Expand All @@ -68,9 +73,15 @@ def __showResponseInfoDialog(self):
dialog = ResponseInfoDialog(self.__result_info, parent=self)
dialog.exec()

def __showFileListDialog(self):
if self.__result_info:
dialog = FileTableDialog(self.__result_info, parent=self)
dialog.exec()

def afterResponse(self, arg):
self.toggleGUI(True)
self.__result_info = arg
self._nameLbl.setText(arg.model)
self.__favorite(True if arg.favorite else False, insert_f=False)

if arg.is_json_response_available:
Expand All @@ -85,10 +96,6 @@ def toggleGUI(self, f: bool):
self.__infoBtn.setEnabled(f)
self.__speakerBtn.setEnabled(f)

def __setResponseInfo(self, arg: ChatMessageContainer):
self.__result_info = arg
self.__favorite(True if arg.favorite else False, insert_f=False)

def getResponseInfo(self):
"""
Get the response information
Expand Down
4 changes: 2 additions & 2 deletions pyqt_openai/chat_widget/center/chatHome.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
DEFAULT_APP_NAME,
HOW_TO_GET_OPENAI_API_KEY_URL,
LARGE_LABEL_PARAM,
MEDIUM_LABEL_PARAM,
MEDIUM_LABEL_PARAM, QUICKSTART_MANUAL_URL,
)
from pyqt_openai.lang.translations import LangClass
from pyqt_openai.widgets.linkLabel import LinkLabel
Expand All @@ -30,7 +30,7 @@ def __initUi(self):

self.__quickStartManualLbl = LinkLabel()
self.__quickStartManualLbl.setText(LangClass.TRANSLATIONS["Quick Start Manual"])
self.__quickStartManualLbl.setUrl(HOW_TO_GET_OPENAI_API_KEY_URL)
self.__quickStartManualLbl.setUrl(QUICKSTART_MANUAL_URL)
self.__quickStartManualLbl.setFont(QFont(*MEDIUM_LABEL_PARAM))
self.__quickStartManualLbl.setAlignment(Qt.AlignmentFlag.AlignCenter)

Expand Down
6 changes: 5 additions & 1 deletion pyqt_openai/chat_widget/center/chatUnit.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
QVBoxLayout,
QHBoxLayout,
QSpacerItem,
QSizePolicy,
QSizePolicy, QLabel,
)

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

self._icon = RoundedImage()
self._icon.setMaximumSize(*DEFAULT_ICON_SIZE)
self._icon.setStyleSheet('margin-right: 3px;')

self._nameLbl = QLabel()

self._copyBtn = Button()
self._copyBtn.setStyleAndIcon(ICON_COPY)
self._copyBtn.clicked.connect(self.__copy)

lay.addWidget(self._icon)
lay.addWidget(self._nameLbl)
lay.addSpacerItem(QSpacerItem(10, 10, QSizePolicy.Policy.MinimumExpanding))
lay.addWidget(self._copyBtn)
lay.setContentsMargins(2, 2, 2, 2)
Expand Down
30 changes: 30 additions & 0 deletions pyqt_openai/ico/file.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions pyqt_openai/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ class SettingsParamsContainer(Container):
show_as_markdown: bool = True
apply_user_defined_styles: bool = False
run_at_startup: bool = True
manual_update: bool = True

voice_provider: str = TTS_DEFAULT_PROVIDER
voice: str = TTS_DEFAULT_VOICE
Expand Down
Loading

0 comments on commit cb4a6c8

Please sign in to comment.