8000 Merge pull request #152 from yjg30737/Dev · DataSolveProblems/pyqt-openai@c8e6a5f · GitHub
[go: up one dir, main page]

Skip to content

Commit c8e6a5f

Browse files
authored
Merge pull request yjg30737#152 from yjg30737/Dev
v1.2.0
2 parents fc40842 + 37bfcc1 commit c8e6a5f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1305
-660
lines changed

pyproject.toml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,25 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "pyqt-openai"
7-
version = "1.1.1"
7+
version = "1.2.0"
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" }
1111
readme = "README.md"
1212
dependencies = [
1313
"PySide6",
14-
"openai",
1514
"pyperclip",
1615
"jinja2",
17-
"llama-index",
1816
"requests",
19-
"replicate"
17+
"pyaudio",
18+
19+
"openai",
20+
"anthropic",
21+
"google-generativeai",
22+
"llama-index",
23+
"replicate",
2024
]
21-
keywords = ['openai', 'pyqt', 'pyqt5', 'pyqt6', 'pyside6', 'desktop', 'app', 'chatbot', 'gpt', 'replicate']
25+
keywords = ['openai', 'pyqt', 'pyqt5', 'pyqt6', 'pyside6', 'desktop', 'app', 'chatbot', 'gpt', 'replicate', 'gemini', 'claude', 'llama', 'llm']
2226

2327
requires-python = ">= 3.11"
2428
# 3.11

pyqt_openai/__init__.py

Lines changed: 157 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
"""
2-
This file is used to store the constants and the global variables that are used throughout the application.
2+
This file is used to store the constants and the global constants / variables that are used throughout the application.
3+
Constants/Variables that are stored here are used throughout the application for the following purposes:
4+
- Initial values related to the environment settings
5+
- Values used internally within the application (e.g., application name, DB name, table name, etc.)
6+
- Values related to the design and UI of the application
7+
- Default LLM list for the application settings
8+
9+
Constants/Variables that are stored here are not supposed to be changed during the runtime except for __init__.py.
10+
Variables which are used globally and can be changed are stored in globals.py.
311
"""
412

513
import json
@@ -11,6 +19,7 @@
1119
from pathlib import Path
1220

1321
# Load the pyproject.toml file
22+
1423
SRC_DIR = Path(__file__).resolve().parent # VividNode/pyqt_openai
1524
ROOT_DIR = SRC_DIR.parent # VividNode
1625
SETUP_FILENAME = ROOT_DIR / "pyproject.toml"
@@ -100,6 +109,9 @@ def move_updater():
100109
HOW_TO_GET_OPENAI_API_KEY_URL = 'https://medium.com/@yjg30737/how-to-get-your-openai-api-key-e2193850932e'
101110
HOW_TO_EXPORT_CHATGPT_CONVERSATION_HISTORY_URL = 'https://medium.com/@yjg30737/how-to-export-your-chatgpt-conversation-history-caa0946d6349'
102111
HOW_TO_REPLICATE = 'https://medium.com/@yjg30737/10a2cb983ceb'
112+
HOW_TO_GET_CLAUDE_API_KEY_URL = 'https://medium.com/@yjg30737/e771e42c182a'
113+
HOW_TO_GET_GEMINI_API_KEY_URL = 'https://medium.com/@yjg30737/e61a84d64c69'
114+
HOW_TO_GET_LLAMA_API_KEY_URL = 'https://medium.com/@yjg30737/0dc1900e3606'
103115

104116
COLUMN_TO_EXCLUDE_FROM_SHOW_HIDE_CHAT = ['id']
105117
COLUMN_TO_EXCLUDE_FROM_SHOW_HIDE_IMAGE = ['id', 'data']
@@ -124,35 +136,15 @@ def move_updater():
124136

125137
MESSAGE_PADDING = 16
126138
MESSAGE_MAXIMUM_HEIGHT = 800
127-
MAXIMUM_MESSAGES_IN_PARAMETER = 20
128139
MESSAGE_MAXIMUM_HEIGHT_RANGE = 300, 1000
129-
MAXIMUM_MESSAGES_IN_PARAMETER_RANGE = 2, 1000
130140

131141
CONTEXT_DELIMITER = '\n'*2
132142
PROMPT_IMAGE_SCALE = 200, 200
133143
TOAST_DURATION = 3
134144

135-
## OPENAI
136-
OPENAI_REQUEST_URL = 'https://api.openai.com/v1/models'
137-
138-
## PARAMETER - OPENAI CHAT
139-
OPENAI_TEMPERATURE_RANGE = 0, 2
140-
OPENAI_TEMPERATURE_STEP = 0.01
141-
142-
MAX_TOKENS_RANGE = 512, 128000
143-
144-
TOP_P_RANGE = 0, 1
145-
TOP_P_STEP = 0.01
146-
147-
FREQUENCY_PENALTY_RANGE = 0, 2
148-
FREQUENCY_PENALTY_STEP = 0.01
149-
150-
PRESENCE_PENALTY_RANGE = 0, 2
151-
PRESENCE_PENALTY_STEP = 0.01
152-
145+
## ICONS
153146
ICON_PATH = os.path.join(EXEC_PATH, 'ico')
154147

155-
## ICONS
156148
DEFAULT_APP_ICON = os.path.join(EXEC_PATH, 'icon.ico')
157149

158150
ICON_ADD = os.path.join(ICON_PATH, 'add.svg')
@@ -188,6 +180,8 @@ def move_updater():
188180
ICON_VERTICAL_THREE_DOTS = os.path.join(ICON_PATH, 'vertical_three_dots.svg')
189181
ICON_WORD = os.path.join(ICON_PATH, 'word.svg')
190182
ICON_SEND = os.path.join(ICON_PATH, 'send.svg')
183+
ICON_RECORD = os.path.join(ICON_PATH, 'record.svg')
184+
ICON_SPEAKER = os.path.join(ICON_PATH, 'speaker.svg')
191185

192186
## CUSTOMIZE
193187
DEFAULT_ICON_SIZE = (24, 24)
@@ -241,6 +235,7 @@ def move_updater():
241235
DEFAULT_SHORTCUT_LEFT_SIDEBAR_WINDOW = 'Ctrl+L'
242236
DEFAULT_SHORTCUT_RIGHT_SIDEBAR_WINDOW = 'Ctrl+R'
243237
DEFAULT_SHORTCUT_CONTROL_PROMPT_WINDOW = 'Ctrl+Shift+C'
238+
DEFAULT_SHORTCUT_RECORD = 'Ctrl+Shift+R'
244239
DEFAULT_SHORTCUT_SETTING = 'Ctrl+Alt+S'
245240
DEFAULT_SHORTCUT_SEND = 'Ctrl+Return'
246241

@@ -250,14 +245,6 @@ def move_updater():
250245
INI_FILE_NAME = os.path.join(get_config_directory(), 'config.yaml')
251246
LANGUAGE_FILE = os.path.join(get_config_directory(), 'translations.json')
252247

253-
# TODO WILL_REMOVE_AFTER v1.2.0
254-
prev_lang_file = os.path.join(ROOT_DIR, 'lang/translations.json') if os.path.exists(os.path.join(ROOT_DIR, 'lang/translations.json')) else (os.path.join(SRC_DIR, 'lang/translations.json') if os.path.exists(os.path.join(SRC_DIR, 'lang/translations.json')) else None)
255-
if prev_lang_file:
256-
if os.path.exists(prev_lang_file):
257-
shutil.copy(prev_lang_file, LANGUAGE_FILE)
258-
else:
259-
pass
260-
261248
DB_FILE_NAME = 'conv'
262249
FILE_NAME_LENGTH = 32
263250
QFILEDIALOG_DEFAULT_DIRECTORY = os.path.expanduser('~')
@@ -317,7 +304,97 @@ def move_updater():
317304
PROMPT_GROUP_TABLE_NAME = 'prompt_group_tb'
318305
PROMPT_ENTRY_TABLE_NAME = 'prompt_entry_tb'
319306

320-
# DEFAULT JSON FILENAME FOR PROMPT
307+
# AI
308+
## OPENAI
309+
OPENAI_REQUEST_URL = 'https://api.openai.com/v1/models'
310+
311+
## PARAMETER - OPENAI CHAT
312+
OPENAI_TEMPERATURE_RANGE = 0, 2
313+
OPENAI_TEMPERATURE_STEP = 0.01
314+
315+
MAX_TOKENS_RANGE = 512, 128000
316+
317+
TOP_P_RANGE = 0, 1
318+
TOP_P_STEP = 0.01
319+
320+
FREQUENCY_PENALTY_RANGE = 0, 2
321+
FREQUENCY_PENALTY_STEP = 0.01
322+
323+
PRESENCE_PENALTY_RANGE = 0, 2
324+
PRESENCE_PENALTY_STEP = 0.01
325+
326+
## OPENAI WHISPER (TTS, STT)
327+
WHISPER_TTS_VOICE_TYPE = ['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer']
328+
WHISPER_TTS_VOICE_SPEED_RANGE = 0.25, 4.0
329+
WHISPER_TTS_MODEL = 'tts-1'
330+
WHISPER_TTS_DEFAULT_VOICE = 'alloy'
331+
WHISPER_TTS_DEFAULT_SPEED = 1.0
332+
333+
STT_MODEL = 'whisper-1'
334+
335+
# Endpoint
336+
# https://platform.openai.com/docs/models/model-endpoint-compatibility
337+
OPENAI_ENDPOINT_DICT = {
338+
'/v1/chat/completions': ['gpt-4o', 'gpt-4o-mini'],
339+
'/v1/completions': [
340+
'text-davinci-003', 'text-davinci-002', 'text-curie-001', 'text-babbage-001', 'text-ada-001', 'davinci',
341+
'curie', 'babbage', 'ada'
342+
],
343+
'/v1/edits': ['text-davinci-edit-001', 'code-davinci-edit-001'],
344+
'/v1/audio/transcriptions': ['whisper-1'],
345+
'/v1/audio/translations': ['whisper-1'],
346+
'/v1/fine-tunes': ['davinci', 'curie', 'babbage', 'ada'],
347+
'/v1/embeddings': ['text-embedding-ada-002', 'text-search-ada-doc-001'],
348+
'/vi/moderations': ['text-moderation-stable', 'text-moderation-latest']
349+
}
350+
351+
# This doesn't need endpoint
352+
DALLE_ARR = ['dall-e-2', 'dall-e-3']
353+
354+
OPENAI_CHAT_ENDPOINT = '/v1/chat/completions'
355+
356+
# Other models' configuration data
357+
DEFAULT_GEMINI_MODEL = 'gemini-1.5-flash'
358+
LLAMA_REQUEST_URL = "https://api.llama-api.com"
359+
360+
# Overall API configuration data
361+
DEFAULT_API_CONFIGS = [
362+
{
363+
"display_name": "OpenAI",
364+
10000 "env_var_name": "OPENAI_API_KEY",
365+
"api_key": ''
366+
},
367+
{
368+
"display_name": "Gemini",
369+
"env_var_name": "GEMINI_API_KEY",
370+
"api_key": ''
371+
},
372+
{
373+
"display_name": "Claude",
374+
"env_var_name": "CLAUDE_API_KEY",
375+
"api_key": ''
376+
},
377+
{
378+
"display_name": "Llama",
379+
"env_var_name": "LLAMA_API_KEY",
380+
"api_key": ''
381+
}
382+
]
383+
384+
# Dictionary that stores the platform and model pairs
385+
PLATFORM_MODEL_DICT = {
386+
'OpenAI': ['gpt-4o', 'gpt-4o-mini'],
387+
'Gemini': ['gemini-1.5-flash'],
388+
'Claude': ['claude-3-5-sonnet-20240620'],
389+
'Llama': ['llama3-70b']
390+
}
391+
392+
# Constants related to the number of messages LLM will store
393+
MAXIMUM_MESSAGES_IN_PARAMETER = 40
394+
MAXIMUM_MESSAGES_IN_PARAMETER_RANGE = 2, 1000
395+
396+
# PROMPT
397+
## DEFAULT JSON FILENAME FOR PROMPT
321398
AWESOME_CHATGPT_PROMPTS_FILENAME = 'prompt_res/awesome_chatgpt_prompts.json'
322399
ALEX_BROGAN_PROMPT_FILENAME = 'prompt_res/alex_brogan.json'
323400

@@ -357,12 +434,45 @@ def move_updater():
357434
}
358435
]'''
359436

360-
# Load the default prompt
437+
## Load the default prompt
361438
if os.path.exists(AWESOME_CHATGPT_PROMPTS_FILENAME):
362439
AWESOME_CHATGPT_PROMPTS = json.load(open(AWESOME_CHATGPT_PROMPTS_FILENAME))[0]
363440
if os.path.exists(ALEX_BROGAN_PROMPT_FILENAME):
364441
ALEX_BROGAN_PROMPT = json.load(open(ALEX_BROGAN_PROMPT_FILENAME))[0]
365442

443+
## Data for random prompt generating feature for image generation
444+
hair_color_randomizer = ['blonde hair', 'red hair', 'blue hair', 'dark hair', 'green hair', 'white hair']
445+
hair_style_randomizer = ['Long straight hair', 'Short pixie cut', 'Bob haircut', 'Layered haircut', 'Curly hair', 'Wavy hair', 'Ponytail', 'Messy bun', 'French braid', 'Dutch braid', 'Fishtail braid', 'High bun', 'Low bun', 'Top knot', 'Half-up half-down hairstyle', 'Braided crown', 'Side-swept bangs', 'Bangs/fringe', 'Chignon', 'Waterfall braid', 'Mohawk', 'Beach waves', 'Updo', 'French twist', 'Cornrows', 'Dreadlocks', 'Pigtails', 'Space buns', 'Sock bun']
446+
clothes_randomizer = ['wearing denim jacket', 'wearing coat', 'wearing blazer', 'wearing blouse', 'wearing biker clothes', 'wearing distressed jeans', 'wearing hoodie']
447+
expression_randomizer = ['Smile', 'Grin', 'Closed eyes', 'Squinting', '(laughing:1.2)', '(giggle:1.2)', '(Angry face:1.4)', 'Frowning face', 'Confused face', 'Boredom', 'Eyebrow furrow', 'Eye roll', 'Smirk']
448+
pose_randomizer = ['sitting', 'lying', 'leaning', 'cross-legged']
449+
camera_distance_randomizer = ['(extreme close-up:1.5)', '(medium full shot:1.5)', '(close-up:1.5)', '(establishing shot:1.5)', '(medium close-up:1.5)', '(point-of-view:1.5)', '(medium shot:1.5)', '(cowboy shot:1.5)', '(long shot:1.5)', '(upper body:1.5)', '(full shot:1.5)', '(full body:1.5)']
450+
camera_angle_randomizer = ['(front view:1.5)', '(from below:1.5)', '(bilaterally symmetrical:1.5)', '(from behind:1.5)', '(side view:1.5)', '(wide angle view:1.5)', '(back view:1.5)', '(fisheyes view:1.5)',
451+
'(from above:1.5)', '(macro view:1.5)',
452+
'(overhead shot:1.5)', '(straight on:1.5)', '(top down view:1.5)', '(hero view:1.5)',
453+
"(bird's eye view:1.5)", '(low view:1.5)', '(high angle:1.5)',
454+
"(worm's eye view:1.5)", '(slightly above:1.5)', '(selfie:1.5)']
455+
456+
adding_lighting_randomizer = ['bloom', 'backlight', 'sun light', 'soft lighting', 'god rays', 'studio light', 'hard lighting', 'volumetic lighting', 'bioluminescent light']
457+
wind_randomizer = ['(wind:0)', '(wind:0.5)', '(wind:1)', '(wind:1.5)', '(wind:2)']
458+
acc1_randomizer = ['wearing sunglasses', 'tattoo']
459+
acc3_randomizer = ['wearing beanie', 'wearing beret', 'wearing cap', 'wearing fedora']
460+
attr2_randomizer = ['put on earphones', 'piercing on nose', 'put on headphones']
461+
location_randomizer = ['In the office', 'Tokyo street', 'In the living room', 'In the music studio', 'On the beach', 'In the club']
462+
463+
RANDOMIZING_PROMPT_SOURCE_ARR = [
464+
hair_color_randomizer,
465+
hair_style_randomizer,
466+
clothes_randomizer,
467+
expression_randomizer,
468+
pose_randomizer,
469+
camera_distance_randomizer,
470+
camera_angle_randomizer,
471+
adding_lighting_randomizer,
472+
wind_randomizer,
473+
acc1_randomizer,
474+
]
475+
366476
# DEFAULT Configuration data for the application settings
367477
# Initialize here to avoid circular import
368478
# ----------------------------
@@ -399,10 +509,16 @@ def move_updater():
399509
'ai_image': DEFAULT_AI_IMAGE_PATH,
400510
'font_size': DEFAULT_FONT_SIZE,
401511
'font_family': DEFAULT_FONT_FAMILY,
402-
'API_KEY': '',
403512
'llama_index_directory': '',
404513
'apply_user_defined_styles': False,
405514
'focus_mode': False,
515+
'voice': WHISPER_TTS_DEFAULT_VOICE,
516+
'voice_speed': WHISPER_TTS_DEFAULT_SPEED,
517+
518+
'OPENAI_API_KEY': '',
519+
'GEMINI_API_KEY': '',
520+
'CLAUDE_API_KEY': '',
521+
'LLAMA_API_KEY': ''
406522
},
407523
'DALLE': {
408524
'quality': 'standard',
@@ -441,9 +557,16 @@ def move_updater():
441557
}
442558
}
443559

560+
# Dynamically add the API keys to the configuration data
561+
def update_general_config_with_api_keys(config_data, api_configs):
562+
for config in api_configs:
563+
config_data['General'][config['env_var_name']] = config['api_key']
564+
565+
update_general_config_with_api_keys(CONFIG_DATA, DEFAULT_API_CONFIGS)
566+
444567
# Update the __all__ list with the PEP8 standard dunder names
445568
__all__ = ['__version__',
446569
'__author__']
447570

448571
# Update the __all__ list with the constants
449-
__all__.extend([name for name, value in globals().items() if name.isupper()])
572+
__all__.extend([name for name, value in globals().items() if name.isupper()])

0 commit comments

Comments
 (0)
0