pygpt-net 2.7.8__py3-none-any.whl → 2.7.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. pygpt_net/CHANGELOG.txt +14 -0
  2. pygpt_net/LICENSE +1 -1
  3. pygpt_net/__init__.py +3 -3
  4. pygpt_net/config.py +15 -1
  5. pygpt_net/controller/chat/common.py +5 -4
  6. pygpt_net/controller/chat/image.py +3 -3
  7. pygpt_net/controller/chat/stream.py +76 -41
  8. pygpt_net/controller/chat/stream_worker.py +3 -3
  9. pygpt_net/controller/ctx/extra.py +3 -1
  10. pygpt_net/controller/dialogs/debug.py +37 -8
  11. pygpt_net/controller/kernel/kernel.py +3 -7
  12. pygpt_net/controller/lang/custom.py +25 -12
  13. pygpt_net/controller/lang/lang.py +45 -3
  14. pygpt_net/controller/lang/mapping.py +15 -2
  15. pygpt_net/controller/notepad/notepad.py +68 -25
  16. pygpt_net/controller/presets/editor.py +5 -1
  17. pygpt_net/controller/presets/presets.py +17 -5
  18. pygpt_net/controller/realtime/realtime.py +13 -1
  19. pygpt_net/controller/theme/theme.py +11 -2
  20. pygpt_net/controller/ui/tabs.py +1 -1
  21. pygpt_net/core/ctx/output.py +38 -12
  22. pygpt_net/core/db/database.py +4 -2
  23. pygpt_net/core/debug/console/console.py +30 -2
  24. pygpt_net/core/debug/context.py +2 -1
  25. pygpt_net/core/debug/ui.py +26 -4
  26. pygpt_net/core/filesystem/filesystem.py +6 -2
  27. pygpt_net/core/notepad/notepad.py +2 -2
  28. pygpt_net/core/tabs/tabs.py +79 -19
  29. pygpt_net/data/config/config.json +4 -3
  30. pygpt_net/data/config/models.json +37 -22
  31. pygpt_net/data/config/settings.json +12 -0
  32. pygpt_net/data/locale/locale.ar.ini +1833 -0
  33. pygpt_net/data/locale/locale.bg.ini +1833 -0
  34. pygpt_net/data/locale/locale.cs.ini +1833 -0
  35. pygpt_net/data/locale/locale.da.ini +1833 -0
  36. pygpt_net/data/locale/locale.de.ini +4 -1
  37. pygpt_net/data/locale/locale.en.ini +70 -67
  38. pygpt_net/data/locale/locale.es.ini +4 -1
  39. pygpt_net/data/locale/locale.fi.ini +1833 -0
  40. pygpt_net/data/locale/locale.fr.ini +4 -1
  41. pygpt_net/data/locale/locale.he.ini +1833 -0
  42. pygpt_net/data/locale/locale.hi.ini +1833 -0
  43. pygpt_net/data/locale/locale.hu.ini +1833 -0
  44. pygpt_net/data/locale/locale.it.ini +4 -1
  45. pygpt_net/data/locale/locale.ja.ini +1833 -0
  46. pygpt_net/data/locale/locale.ko.ini +1833 -0
  47. pygpt_net/data/locale/locale.nl.ini +1833 -0
  48. pygpt_net/data/locale/locale.no.ini +1833 -0
  49. pygpt_net/data/locale/locale.pl.ini +5 -2
  50. pygpt_net/data/locale/locale.pt.ini +1833 -0
  51. pygpt_net/data/locale/locale.ro.ini +1833 -0
  52. pygpt_net/data/locale/locale.ru.ini +1833 -0
  53. pygpt_net/data/locale/locale.sk.ini +1833 -0
  54. pygpt_net/data/locale/locale.sv.ini +1833 -0
  55. pygpt_net/data/locale/locale.tr.ini +1833 -0
  56. pygpt_net/data/locale/locale.uk.ini +4 -1
  57. pygpt_net/data/locale/locale.zh.ini +4 -1
  58. pygpt_net/item/notepad.py +8 -2
  59. pygpt_net/migrations/Version20260121190000.py +25 -0
  60. pygpt_net/migrations/Version20260122140000.py +25 -0
  61. pygpt_net/migrations/__init__.py +5 -1
  62. pygpt_net/preload.py +246 -3
  63. pygpt_net/provider/api/__init__.py +16 -2
  64. pygpt_net/provider/api/anthropic/__init__.py +21 -7
  65. pygpt_net/provider/api/google/__init__.py +21 -7
  66. pygpt_net/provider/api/google/image.py +89 -2
  67. pygpt_net/provider/api/google/realtime/client.py +70 -24
  68. pygpt_net/provider/api/google/realtime/realtime.py +48 -12
  69. pygpt_net/provider/api/google/video.py +2 -2
  70. pygpt_net/provider/api/openai/__init__.py +26 -11
  71. pygpt_net/provider/api/openai/image.py +79 -3
  72. pygpt_net/provider/api/openai/realtime/realtime.py +26 -6
  73. pygpt_net/provider/api/openai/responses.py +11 -31
  74. pygpt_net/provider/api/openai/video.py +2 -2
  75. pygpt_net/provider/api/x_ai/__init__.py +21 -10
  76. pygpt_net/provider/api/x_ai/realtime/client.py +185 -146
  77. pygpt_net/provider/api/x_ai/realtime/realtime.py +30 -15
  78. pygpt_net/provider/api/x_ai/remote_tools.py +83 -0
  79. pygpt_net/provider/api/x_ai/tools.py +51 -0
  80. pygpt_net/provider/core/config/patch.py +12 -1
  81. pygpt_net/provider/core/model/patch.py +36 -1
  82. pygpt_net/provider/core/notepad/db_sqlite/storage.py +53 -10
  83. pygpt_net/tools/agent_builder/ui/dialogs.py +2 -1
  84. pygpt_net/tools/audio_transcriber/ui/dialogs.py +2 -1
  85. pygpt_net/tools/code_interpreter/ui/dialogs.py +2 -1
  86. pygpt_net/tools/html_canvas/ui/dialogs.py +2 -1
  87. pygpt_net/tools/image_viewer/ui/dialogs.py +3 -5
  88. pygpt_net/tools/indexer/ui/dialogs.py +2 -1
  89. pygpt_net/tools/media_player/ui/dialogs.py +2 -1
  90. pygpt_net/tools/translator/ui/dialogs.py +2 -1
  91. pygpt_net/tools/translator/ui/widgets.py +6 -2
  92. pygpt_net/ui/dialog/about.py +2 -2
  93. pygpt_net/ui/dialog/db.py +2 -1
  94. pygpt_net/ui/dialog/debug.py +169 -6
  95. pygpt_net/ui/dialog/logger.py +6 -2
  96. pygpt_net/ui/dialog/models.py +36 -3
  97. pygpt_net/ui/dialog/preset.py +5 -1
  98. pygpt_net/ui/dialog/remote_store.py +2 -1
  99. pygpt_net/ui/main.py +3 -2
  100. pygpt_net/ui/widget/dialog/editor_file.py +2 -1
  101. pygpt_net/ui/widget/lists/debug.py +12 -7
  102. pygpt_net/ui/widget/option/checkbox.py +2 -8
  103. pygpt_net/ui/widget/option/combo.py +10 -2
  104. pygpt_net/ui/widget/textarea/console.py +156 -7
  105. pygpt_net/ui/widget/textarea/highlight.py +66 -0
  106. pygpt_net/ui/widget/textarea/input.py +624 -57
  107. pygpt_net/ui/widget/textarea/notepad.py +294 -27
  108. {pygpt_net-2.7.8.dist-info → pygpt_net-2.7.10.dist-info}/LICENSE +1 -1
  109. {pygpt_net-2.7.8.dist-info → pygpt_net-2.7.10.dist-info}/METADATA +16 -64
  110. {pygpt_net-2.7.8.dist-info → pygpt_net-2.7.10.dist-info}/RECORD +112 -91
  111. {pygpt_net-2.7.8.dist-info → pygpt_net-2.7.10.dist-info}/WHEEL +0 -0
  112. {pygpt_net-2.7.8.dist-info → pygpt_net-2.7.10.dist-info}/entry_points.txt +0 -0
@@ -28,6 +28,7 @@ action.group.remove = Видалити з групи
28
28
  action.idx = Індексувати за допомогою LlamaIndex...
29
29
  action.idx.remove = Видалити з
30
30
  action.import = Імпорт
31
+ action.mark = Виділити маркером
31
32
  action.mkdir = Створити каталог...
32
33
  action.move_to = Перемістити до
33
34
  action.new = Новий...
@@ -67,6 +68,7 @@ action.tab.move.right = Перемістити в праву колонку
67
68
  action.touch = Створити файл...
68
69
  action.truncate = Очистити все
69
70
  action.undo = Скасувати
71
+ action.unmark = Прибрати виділення маркером
70
72
  action.unpack = Розпакувати
71
73
  action.unpin = Відкріпити
72
74
  action.upload = Завантажте файли тут...
@@ -690,7 +692,7 @@ event.control.voice_cmd.toggle = Керування голосом: Перемк
690
692
  event.control.voice_msg.start = Голосовий вхід: Розпочати
691
693
  event.control.voice_msg.stop = Голосовий вхід: Зупинити
692
694
  event.control.voice_msg.toggle = Голосовий вхід: Перемкнути
693
- exit.msg = Вам подобається PyGPT? Підтримайте розвиток проєкту:
695
+ exit.msg = Підтримайте розвиток PyGPT:
694
696
  expert.wait.failed: Виклик експерта не вдався
695
697
  expert.wait.status: Очікування експерта...
696
698
  files.delete.confirm = Видалити файл/директорію?
@@ -762,6 +764,7 @@ input.btn.send = Відправити
762
764
  input.btn.stop = Зупинити
763
765
  input.btn.update = Оновити
764
766
  input.label = Вхід (Ваш запит)
767
+ input.placeholder = Натисніть CTRL + стрілки вгору/вниз для історії підказок...
765
768
  input.radio.enter = Введення
766
769
  input.radio.enter_shift = Shift+Enter
767
770
  input.radio.none = Вимкнено
@@ -28,6 +28,7 @@ action.group.remove = 从组中移除
28
28
  action.idx = 使用LlamaIndex索引...
29
29
  action.idx.remove = 從中移除
30
30
  action.import = 导入
31
+ action.mark = 高亮
31
32
  action.mkdir = 創建目錄...
32
33
  action.move_to = 移动到
33
34
  action.new = 新建...
@@ -67,6 +68,7 @@ action.tab.move.right = 移到右列
67
68
  action.touch = 創建文件...
68
69
  action.truncate = 截斷
69
70
  action.undo = 撤銷
71
+ action.unmark = 取消高亮
70
72
  action.unpack = 解压
71
73
  action.unpin = 取消置頂
72
74
  action.upload = 在這裡上傳文件...
@@ -690,7 +692,7 @@ event.control.voice_cmd.toggle = 语音控制:切换
690
692
  event.control.voice_msg.start = 语音输入:开始
691
693
  event.control.voice_msg.stop = 语音输入:停止
692
694
  event.control.voice_msg.toggle = 语音输入:切换
693
- exit.msg = 你喜欢PyGPT吗?支持项目的发展:
695
+ exit.msg = 支持PyGPT的发展:
694
696
  expert.wait.failed: 调用专家失败
695
697
  expert.wait.status: 等待专家...
696
698
  files.delete.confirm = 刪除文件/目錄?
@@ -762,6 +764,7 @@ input.btn.send = 發送
762
764
  input.btn.stop = 停止
763
765
  input.btn.update = 更新
764
766
  input.label = 輸入(您的提示)
767
+ input.placeholder = 按 CTRL + 上/下方向键查看提示历史...
765
768
  input.radio.enter = 回車
766
769
  input.radio.enter_shift = Shift+回車
767
770
  input.radio.none = 關閉
pygpt_net/item/notepad.py CHANGED
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.09.05 18:00:00 #
9
+ # Updated Date: 2026.01.22 16:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import json
@@ -26,6 +26,8 @@ class NotepadItem:
26
26
  created: int = 0
27
27
  updated: int = 0
28
28
  initialized: bool = False
29
+ highlights: Optional[list] = None
30
+ scroll_pos: int = -1
29
31
 
30
32
  def __init__(self):
31
33
  self.id = 0
@@ -38,6 +40,8 @@ class NotepadItem:
38
40
  self.created = ts
39
41
  self.updated = ts
40
42
  self.initialized = False
43
+ self.highlights = []
44
+ self.scroll_pos = -1
41
45
 
42
46
  def to_dict(self):
43
47
  return {
@@ -49,7 +53,9 @@ class NotepadItem:
49
53
  'deleted': self.deleted,
50
54
  'created': self.created,
51
55
  'updated': self.updated,
52
- 'initialized': self.initialized
56
+ 'initialized': self.initialized,
57
+ 'highlights': self.highlights,
58
+ 'scroll_pos': self.scroll_pos,
53
59
  }
54
60
 
55
61
  def dump(self):
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2026.01.21 20:00:00 #
10
+ # ================================================== #
11
+
12
+ from sqlalchemy import text
13
+
14
+ from .base import BaseMigration
15
+
16
+
17
+ class Version20260121190000(BaseMigration):
18
+ def __init__(self, window=None):
19
+ super(Version20260121190000, self).__init__(window)
20
+ self.window = window
21
+
22
+ def up(self, conn):
23
+ conn.execute(text("""
24
+ ALTER TABLE notepad ADD COLUMN highlights_json TEXT;
25
+ """))
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2026.01.22 16:00:00 #
10
+ # ================================================== #
11
+
12
+ from sqlalchemy import text
13
+
14
+ from .base import BaseMigration
15
+
16
+
17
+ class Version20260122140000(BaseMigration):
18
+ def __init__(self, window=None):
19
+ super(Version20260122140000, self).__init__(window)
20
+ self.window = window
21
+
22
+ def up(self, conn):
23
+ conn.execute(text("""
24
+ ALTER TABLE notepad ADD COLUMN scroll_pos INTEGER DEFAULT -1;
25
+ """))
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2026.01.02 20:00:00 #
9
+ # Updated Date: 2026.01.22 16:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from .Version20231227152900 import Version20231227152900 # 2.0.59
@@ -24,6 +24,8 @@ from .Version20241122130000 import Version20241122130000 # 2.4.21
24
24
  from .Version20241126170000 import Version20241126170000 # 2.4.34
25
25
  from .Version20241215110000 import Version20241215110000 # 2.4.43
26
26
  from .Version20260102190000 import Version20260102190000 # 2.7.5
27
+ from .Version20260121190000 import Version20260121190000 # 2.7.10
28
+ from .Version20260122140000 import Version20260122140000 # 2.7.10
27
29
 
28
30
  class Migrations:
29
31
  def __init__(self):
@@ -52,4 +54,6 @@ class Migrations:
52
54
  Version20241126170000(), # 2.4.34
53
55
  Version20241215110000(), # 2.4.43
54
56
  Version20260102190000(), # 2.7.5
57
+ Version20260121190000(), # 2.7.10
58
+ Version20260122140000(), # 2.7.10
55
59
  ]
pygpt_net/preload.py CHANGED
@@ -6,9 +6,12 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.12.31 17:00:00 #
9
+ # Updated Date: 2026.01.21 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
+ LINK_GITHUB = "https://github.com/szczyglis-dev/py-gpt"
13
+ LINK_DONATE = "https://www.buymeacoffee.com/szczyglis"
14
+
12
15
  # -------------------------------------------------- #
13
16
  # Lightweight splash window (separate process)
14
17
  # -------------------------------------------------- #
@@ -17,12 +20,193 @@ def _splash_main(conn, title="PyGPT", message="Loading…"):
17
20
  Minimal splash process using PySide6. Runs its own event loop and
18
21
  listens for commands on a Pipe: {"type": "msg", "text": "..."} or {"type": "quit"}.
19
22
  """
23
+ STRING_MAPPING = {
24
+ "en": {
25
+ "init": "Initializing...",
26
+ "support": "Support the project:",
27
+ "github": "⭐ Star on GitHub",
28
+ "donate": "☕ Buy me a coffee",
29
+ },
30
+ "pl": {
31
+ "init": "Inicjalizacja...",
32
+ "support": "Wesprzyj projekt:",
33
+ "github": "⭐ Gwiazdka na GitHub",
34
+ "donate": "☕ Postaw mi kawę",
35
+ },
36
+ "de": {
37
+ "init": "Initialisierung...",
38
+ "support": "Unterstütze das Projekt:",
39
+ "github": "⭐ Auf GitHub starren",
40
+ "donate": "☕ Kauf mir einen Kaffee",
41
+ },
42
+ "es": {
43
+ "init": "Inicializando...",
44
+ "support": "Apoya el proyecto:",
45
+ "github": "⭐ Estrella en GitHub",
46
+ "donate": "☕ Cómprame un café",
47
+ },
48
+ "fr": {
49
+ "init": "Initialisation...",
50
+ "support": "Soutenez le projet :",
51
+ "github": "⭐ Étoile sur GitHub",
52
+ "donate": "☕ Offrez-moi un café",
53
+ },
54
+ "it": {
55
+ "init": "Inizializzazione...",
56
+ "support": "Supporta il progetto:",
57
+ "github": "⭐ Metti una stella su GitHub",
58
+ "donate": "☕ Offrimi un caffè",
59
+ },
60
+ "uk": {
61
+ "init": "Ініціалізація...",
62
+ "support": "Підтримайте проєкт:",
63
+ "github": "⭐ Зірка на GitHub",
64
+ "donate": "☕ Купи мені каву",
65
+ },
66
+ "ru": {
67
+ "init": "Инициализация...",
68
+ "support": "Поддержите проект:",
69
+ "github": "⭐ Звезда на GitHub",
70
+ "donate": "☕ Купи мне кофе",
71
+ },
72
+ "zh": {
73
+ "init": "正在初始化...",
74
+ "support": "支持该项目:",
75
+ "github": "⭐ 在 GitHub 上加星",
76
+ "donate": "☕ 请我喝杯咖啡",
77
+ },
78
+ "ja": {
79
+ "init": "初期化中...",
80
+ "support": "プロジェクトをサポート:",
81
+ "github": "⭐ GitHubでスターを付ける",
82
+ "donate": "☕ コーヒーをご馳走する",
83
+ },
84
+ "ar": {
85
+ "init": "جارٍ التهيئة...",
86
+ "support": "ادعم المشروع:",
87
+ "github": "⭐ نجمة على GitHub",
88
+ "donate": "☕ اشترِ لي قهوة",
89
+ },
90
+ "pt": {
91
+ "init": "Iniciando...",
92
+ "support": "Apoie o projeto:",
93
+ "github": "⭐ Estrela no GitHub",
94
+ "donate": "☕ Compre-me um café",
95
+ },
96
+ "hi": {
97
+ "init": "प्रारंभ हो रहा है...",
98
+ "support": "परियोजना का समर्थन करें:",
99
+ "github": "⭐ GitHub पर स्टार करें",
100
+ "donate": "☕ मुझे एक कॉफी खरीदें",
101
+ },
102
+ "ko": {
103
+ "init": "초기화 중...",
104
+ "support": "프로젝트 지원:",
105
+ "github": "⭐ GitHub에서 별표 표시",
106
+ "donate": "☕ 커피 한 잔 사주세요",
107
+ },
108
+ "tr": {
109
+ "init": "Başlatılıyor...",
110
+ "support": "Projeyi destekleyin:",
111
+ "github": "⭐ GitHub'da Yıldız Ver",
112
+ "donate": "☕ Bana bir kahve ısmarla",
113
+ },
114
+ "he": {
115
+ "init": "אתחול...",
116
+ "support": "תמכו בפרויקט:",
117
+ "github": "⭐ כוכב ב-GitHub",
118
+ "donate": "☕ קנו לי קפה",
119
+ },
120
+ "nl": {
121
+ "init": "Initialiseren...",
122
+ "support": "Steun het project:",
123
+ "github": "⭐ Ster op GitHub",
124
+ "donate": "☕ Koop me een koffie",
125
+ },
126
+ "sv": {
127
+ "init": "Initierar...",
128
+ "support": "Stöd projektet:",
129
+ "github": "⭐ Stjärna på GitHub",
130
+ "donate": "☕ Köp en kaffe till mig",
131
+ },
132
+ "fi": {
133
+ "init": "Alustetaan...",
134
+ "support": "Tue projektia:",
135
+ "github": "⭐ Tähti GitHubissa",
136
+ "donate": "☕ Osta minulle kahvi",
137
+ },
138
+ "no": {
139
+ "init": "Initialiserer...",
140
+ "support": "Støtt prosjektet:",
141
+ "github": "⭐ Stjerne på GitHub",
142
+ "donate": "☕ Kjøp meg en kaffe",
143
+ },
144
+ "da": {
145
+ "init": "Initialiserer...",
146
+ "support": "Støt projektet:",
147
+ "github": "⭐ Stjerne på GitHub",
148
+ "donate": "☕ Køb mig en kaffe",
149
+ },
150
+ "cs": {
151
+ "init": "Inicializuji...",
152
+ "support": "Podpořte projekt:",
153
+ "github": "⭐ Ohodnoťte na GitHubu",
154
+ "donate": "☕ Kup mi kávu",
155
+ },
156
+ "sk": {
157
+ "init": "Inicializácia...",
158
+ "support": "Podporte projekt:",
159
+ "github": "⭐ Ohodnoťte na GitHube",
160
+ "donate": "☕ Kúp mi kávu",
161
+ },
162
+ "bg": {
163
+ "init": "Инициализация...",
164
+ "support": "Подкрепете проекта:",
165
+ "github": "⭐ Оценете в GitHub",
166
+ "donate": "☕ Купете ми кафе",
167
+ },
168
+ "hu": {
169
+ "init": "Inicializálás...",
170
+ "support": "Támogassa a projektet:",
171
+ "github": "⭐ Csillag a GitHubon",
172
+ "donate": "☕ Vegyél nekem egy kávét",
173
+ },
174
+ "ro": {
175
+ "init": "Se inițializează...",
176
+ "support": "Susține proiectul:",
177
+ "github": "⭐ Evaluează pe GitHub",
178
+ "donate": "☕ Cumpără-mi o cafea",
179
+ },
180
+ }
181
+
182
+
183
+ """
184
+ "cs": "Čeština",
185
+ "sk": "Slovenčina",
186
+ "bg": "Български",
187
+ "hu": "Magyar",
188
+ "ro": "Română",
189
+ """
190
+
20
191
  try:
21
192
  # Import locally to keep the main process import path untouched
22
193
  from PySide6 import QtCore, QtWidgets
194
+ from pygpt_net.config import quick_get_config_value
23
195
  except Exception:
24
196
  return
25
197
 
198
+ # Try to get language from config
199
+ try:
200
+ lang = quick_get_config_value("lang", "en")
201
+ except Exception:
202
+ lang = "en"
203
+
204
+ strings = STRING_MAPPING.get(lang, STRING_MAPPING["en"])
205
+ msg_init = strings.get("init", message)
206
+ msg_support = strings.get("support", "Support the project:")
207
+ msg_github = strings.get("github", "⭐ Star on GitHub")
208
+ msg_donate = strings.get("donate", "☕ Buy me a coffee")
209
+
26
210
  try:
27
211
  # Enable HiDPI (safe defaults)
28
212
  try:
@@ -60,10 +244,68 @@ def _splash_main(conn, title="PyGPT", message="Loading…"):
60
244
  lbl_title.setAlignment(QtCore.Qt.AlignCenter)
61
245
  lbl_title.setStyleSheet("font-size: 16px; font-weight: 600;")
62
246
 
63
- lbl_wait = QtWidgets.QLabel("Initializing...")
247
+ lbl_wait = QtWidgets.QLabel(msg_init)
64
248
  lbl_wait.setAlignment(QtCore.Qt.AlignCenter)
65
249
  lbl_wait.setStyleSheet("font-size: 12px;")
66
250
 
251
+ lbl_support = QtWidgets.QLabel(msg_support)
252
+ lbl_support.setAlignment(QtCore.Qt.AlignCenter)
253
+ lbl_support.setStyleSheet("font-size: 12px;")
254
+
255
+ btn_support = QtWidgets.QPushButton(msg_github)
256
+ btn_support.setCursor(QtCore.Qt.PointingHandCursor)
257
+ btn_support.setStyleSheet("""
258
+ QPushButton {
259
+ background-color: #444444;
260
+ color: #ffffff;
261
+ border: none;
262
+ border-radius: 6px;
263
+ padding: 6px 12px;
264
+ font-size: 12px;
265
+ }
266
+ QPushButton:hover {
267
+ background-color: #555555;
268
+ }
269
+ QPushButton:pressed {
270
+ background-color: #333333;
271
+ }
272
+ """)
273
+ def open_github():
274
+ import webbrowser
275
+ webbrowser.open(LINK_GITHUB)
276
+ btn_support.clicked.connect(open_github)
277
+
278
+ btn_donate = QtWidgets.QPushButton(msg_donate)
279
+ btn_donate.setCursor(QtCore.Qt.PointingHandCursor)
280
+ btn_donate.setStyleSheet("""
281
+ QPushButton {
282
+ background-color: #444444;
283
+ color: #ffffff;
284
+ border: none;
285
+ border-radius: 6px;
286
+ padding: 6px 12px;
287
+ font-size: 12px;
288
+ }
289
+ QPushButton:hover {
290
+ background-color: #555555;
291
+ }
292
+ QPushButton:pressed {
293
+ background-color: #333333;
294
+ }
295
+ """)
296
+ def open_donate():
297
+ import webbrowser
298
+ webbrowser.open(LINK_DONATE)
299
+ btn_donate.clicked.connect(open_donate)
300
+
301
+ support_layout = QtWidgets.QHBoxLayout()
302
+ support_layout.addWidget(btn_support)
303
+ support_layout.addWidget(btn_donate)
304
+
305
+ support_area = QtWidgets.QVBoxLayout()
306
+ support_area.addWidget(lbl_support)
307
+ support_area.addLayout(support_layout)
308
+
67
309
  lbl_msg = QtWidgets.QLabel(message, panel)
68
310
  lbl_msg.setAlignment(QtCore.Qt.AlignCenter)
69
311
  lbl_msg.setStyleSheet("font-size: 12px;")
@@ -79,8 +321,9 @@ def _splash_main(conn, title="PyGPT", message="Loading…"):
79
321
  layout.addWidget(lbl_msg)
80
322
  layout.addWidget(bar)
81
323
  layout.addWidget(lbl_wait)
324
+ layout.addLayout(support_area)
82
325
 
83
- panel.setFixedSize(360, 120)
326
+ panel.setFixedSize(360, 220)
84
327
  panel.move(0, 0)
85
328
  root.resize(panel.size())
86
329
 
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.09.05 01:00:00 #
9
+ # Updated Date: 2026.01.21 13:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from .anthropic import ApiAnthropic
@@ -26,4 +26,18 @@ class Api:
26
26
  self.anthropic = ApiAnthropic(window)
27
27
  self.google = ApiGoogle(window)
28
28
  self.openai = ApiOpenAI(window)
29
- self.xai = ApiXAI(window)
29
+ self.xai = ApiXAI(window)
30
+
31
+ def stop(self):
32
+ """Stop all API clients"""
33
+ self.anthropic.stop()
34
+ self.google.stop()
35
+ self.openai.stop()
36
+ self.xai.stop()
37
+
38
+ def close(self):
39
+ """Close all API clients"""
40
+ self.anthropic.safe_close()
41
+ self.google.safe_close()
42
+ self.openai.safe_close()
43
+ self.xai.safe_close()
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2026.01.05 20:00:00 #
9
+ # Updated Date: 2026.01.21 13:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, Dict, Any
@@ -155,6 +155,25 @@ class ApiAnthropic:
155
155
  pass
156
156
  return True
157
157
 
158
+ def redirect_call(
159
+ self,
160
+ context: BridgeContext,
161
+ extra: dict = None
162
+ ) -> str:
163
+ """
164
+ Redirect quick call to standard call and return the output text
165
+
166
+ :param context: BridgeContext
167
+ :param extra: Extra parameters
168
+ :return: Output text
169
+ """
170
+ context.stream = False
171
+ context.mode = MODE_CHAT
172
+ self.locked = True
173
+ self.call(context, extra)
174
+ self.locked = False
175
+ return context.ctx.output
176
+
158
177
  def quick_call(
159
178
  self,
160
179
  context: BridgeContext,
@@ -168,12 +187,7 @@ class ApiAnthropic:
168
187
  :return: Output text
169
188
  """
170
189
  if context.request:
171
- context.stream = False
172
- context.mode = MODE_CHAT
173
- self.locked = True
174
- self.call(context, extra)
175
- self.locked = False
176
- return context.ctx.output
190
+ return self.redirect_call(context, extra)
177
191
 
178
192
  self.locked = True
179
193
  try:
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2026.01.03 17:00:00 #
9
+ # Updated Date: 2026.01.21 13:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -204,6 +204,25 @@ class ApiGoogle:
204
204
  pass
205
205
  return True
206
206
 
207
+ def redirect_call(
208
+ self,
209
+ context: BridgeContext,
210
+ extra: dict = None
211
+ ) -> str:
212
+ """
213
+ Redirect quick call to standard call and return the output text
214
+
215
+ :param context: BridgeContext
216
+ :param extra: Extra parameters
217
+ :return: Output text
218
+ """
219
+ context.stream = False
220
+ context.mode = MODE_CHAT
221
+ self.locked = True
222
+ self.call(context, extra)
223
+ self.locked = False
224
+ return context.ctx.output
225
+
207
226
  def quick_call(
208
227
  self,
209
228
  context: BridgeContext,
@@ -217,12 +236,7 @@ class ApiGoogle:
217
236
  :return: Output text
218
237
  """
219
238
  if context.request:
220
- context.stream = False
221
- context.mode = MODE_CHAT
222
- self.locked = True
223
- self.call(context, extra)
224
- self.locked = False
225
- return context.ctx.output
239
+ return self.redirect_call(context, extra)
226
240
 
227
241
  self.locked = True
228
242
  try: