pygpt-net 2.6.1__py3-none-any.whl → 2.6.6__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.
- pygpt_net/CHANGELOG.txt +23 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +20 -1
- pygpt_net/config.py +55 -65
- pygpt_net/controller/__init__.py +5 -2
- pygpt_net/controller/calendar/note.py +101 -126
- pygpt_net/controller/chat/chat.py +38 -35
- pygpt_net/controller/chat/render.py +154 -214
- pygpt_net/controller/chat/response.py +5 -3
- pygpt_net/controller/chat/stream.py +92 -27
- pygpt_net/controller/config/config.py +39 -42
- pygpt_net/controller/config/field/checkbox.py +16 -12
- pygpt_net/controller/config/field/checkbox_list.py +36 -31
- pygpt_net/controller/config/field/cmd.py +51 -57
- pygpt_net/controller/config/field/combo.py +33 -16
- pygpt_net/controller/config/field/dictionary.py +48 -55
- pygpt_net/controller/config/field/input.py +50 -32
- pygpt_net/controller/config/field/slider.py +40 -45
- pygpt_net/controller/config/field/textarea.py +20 -6
- pygpt_net/controller/config/placeholder.py +110 -231
- pygpt_net/controller/ctx/common.py +48 -48
- pygpt_net/controller/ctx/ctx.py +91 -132
- pygpt_net/controller/lang/mapping.py +57 -95
- pygpt_net/controller/lang/plugins.py +64 -55
- pygpt_net/controller/lang/settings.py +39 -38
- pygpt_net/controller/layout/layout.py +176 -109
- pygpt_net/controller/mode/mode.py +88 -85
- pygpt_net/controller/model/model.py +73 -73
- pygpt_net/controller/plugins/plugins.py +209 -223
- pygpt_net/controller/plugins/presets.py +54 -55
- pygpt_net/controller/plugins/settings.py +54 -69
- pygpt_net/controller/presets/editor.py +33 -88
- pygpt_net/controller/presets/experts.py +20 -1
- pygpt_net/controller/presets/presets.py +293 -298
- pygpt_net/controller/settings/profile.py +16 -4
- pygpt_net/controller/theme/theme.py +72 -81
- pygpt_net/controller/ui/mode.py +118 -186
- pygpt_net/controller/ui/tabs.py +69 -90
- pygpt_net/controller/ui/ui.py +47 -56
- pygpt_net/controller/ui/vision.py +24 -23
- pygpt_net/core/agents/runner.py +15 -7
- pygpt_net/core/bridge/bridge.py +5 -5
- pygpt_net/core/command/command.py +149 -219
- pygpt_net/core/ctx/ctx.py +94 -146
- pygpt_net/core/debug/debug.py +48 -58
- pygpt_net/core/experts/experts.py +3 -3
- pygpt_net/core/models/models.py +74 -112
- pygpt_net/core/modes/modes.py +13 -21
- pygpt_net/core/plugins/plugins.py +154 -177
- pygpt_net/core/presets/presets.py +103 -176
- pygpt_net/core/render/web/body.py +217 -215
- pygpt_net/core/render/web/renderer.py +330 -474
- pygpt_net/core/text/utils.py +28 -44
- pygpt_net/core/tokens/tokens.py +104 -203
- pygpt_net/data/config/config.json +3 -3
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/locale/locale.de.ini +2 -0
- pygpt_net/data/locale/locale.en.ini +2 -0
- pygpt_net/data/locale/locale.es.ini +2 -0
- pygpt_net/data/locale/locale.fr.ini +2 -0
- pygpt_net/data/locale/locale.it.ini +2 -0
- pygpt_net/data/locale/locale.pl.ini +3 -1
- pygpt_net/data/locale/locale.uk.ini +2 -0
- pygpt_net/data/locale/locale.zh.ini +2 -0
- pygpt_net/item/ctx.py +141 -139
- pygpt_net/plugin/agent/plugin.py +2 -1
- pygpt_net/plugin/audio_output/plugin.py +5 -2
- pygpt_net/plugin/base/plugin.py +101 -85
- pygpt_net/plugin/bitbucket/__init__.py +12 -0
- pygpt_net/plugin/bitbucket/config.py +267 -0
- pygpt_net/plugin/bitbucket/plugin.py +126 -0
- pygpt_net/plugin/bitbucket/worker.py +569 -0
- pygpt_net/plugin/cmd_code_interpreter/plugin.py +3 -2
- pygpt_net/plugin/cmd_custom/plugin.py +3 -2
- pygpt_net/plugin/cmd_files/plugin.py +3 -2
- pygpt_net/plugin/cmd_history/plugin.py +3 -2
- pygpt_net/plugin/cmd_mouse_control/plugin.py +5 -2
- pygpt_net/plugin/cmd_serial/plugin.py +3 -2
- pygpt_net/plugin/cmd_system/plugin.py +3 -6
- pygpt_net/plugin/cmd_web/plugin.py +3 -2
- pygpt_net/plugin/experts/plugin.py +2 -2
- pygpt_net/plugin/facebook/__init__.py +12 -0
- pygpt_net/plugin/facebook/config.py +359 -0
- pygpt_net/plugin/facebook/plugin.py +113 -0
- pygpt_net/plugin/facebook/worker.py +698 -0
- pygpt_net/plugin/github/__init__.py +12 -0
- pygpt_net/plugin/github/config.py +441 -0
- pygpt_net/plugin/github/plugin.py +126 -0
- pygpt_net/plugin/github/worker.py +674 -0
- pygpt_net/plugin/google/__init__.py +12 -0
- pygpt_net/plugin/google/config.py +367 -0
- pygpt_net/plugin/google/plugin.py +126 -0
- pygpt_net/plugin/google/worker.py +826 -0
- pygpt_net/plugin/idx_llama_index/plugin.py +3 -2
- pygpt_net/plugin/mailer/plugin.py +3 -5
- pygpt_net/plugin/openai_vision/plugin.py +3 -2
- pygpt_net/plugin/real_time/plugin.py +52 -60
- pygpt_net/plugin/slack/__init__.py +12 -0
- pygpt_net/plugin/slack/config.py +349 -0
- pygpt_net/plugin/slack/plugin.py +115 -0
- pygpt_net/plugin/slack/worker.py +639 -0
- pygpt_net/plugin/telegram/__init__.py +12 -0
- pygpt_net/plugin/telegram/config.py +308 -0
- pygpt_net/plugin/telegram/plugin.py +117 -0
- pygpt_net/plugin/telegram/worker.py +563 -0
- pygpt_net/plugin/twitter/__init__.py +12 -0
- pygpt_net/plugin/twitter/config.py +491 -0
- pygpt_net/plugin/twitter/plugin.py +125 -0
- pygpt_net/plugin/twitter/worker.py +837 -0
- pygpt_net/provider/agents/llama_index/legacy/openai_assistant.py +35 -3
- pygpt_net/tools/code_interpreter/tool.py +0 -1
- pygpt_net/tools/translator/tool.py +1 -1
- pygpt_net/ui/base/config_dialog.py +86 -100
- pygpt_net/ui/base/context_menu.py +48 -46
- pygpt_net/ui/dialog/preset.py +34 -77
- pygpt_net/ui/layout/ctx/ctx_list.py +10 -6
- pygpt_net/ui/layout/toolbox/presets.py +41 -41
- pygpt_net/ui/main.py +49 -31
- pygpt_net/ui/tray.py +61 -60
- pygpt_net/ui/widget/calendar/select.py +86 -70
- pygpt_net/ui/widget/lists/attachment.py +86 -44
- pygpt_net/ui/widget/lists/base_list_combo.py +85 -33
- pygpt_net/ui/widget/lists/context.py +135 -188
- pygpt_net/ui/widget/lists/preset.py +59 -61
- pygpt_net/ui/widget/textarea/web.py +161 -48
- pygpt_net/utils.py +8 -1
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/METADATA +164 -2
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/RECORD +131 -103
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/entry_points.txt +0 -0
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date:
|
|
9
|
+
# Updated Date: 2025.08.15 03:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
|
-
import
|
|
13
|
-
from typing import Dict
|
|
12
|
+
from copy import deepcopy
|
|
13
|
+
from typing import Dict, Optional
|
|
14
14
|
from uuid import uuid4
|
|
15
15
|
|
|
16
16
|
from PySide6.QtGui import QAction
|
|
@@ -30,10 +30,11 @@ class Presets:
|
|
|
30
30
|
self.dialog = False
|
|
31
31
|
self.width = 500
|
|
32
32
|
self.height = 500
|
|
33
|
+
self._sep_action = None
|
|
33
34
|
|
|
34
35
|
def setup(self):
|
|
35
36
|
"""Set up plugin presets"""
|
|
36
|
-
self.window.plugin_presets.setup()
|
|
37
|
+
self.window.plugin_presets.setup()
|
|
37
38
|
|
|
38
39
|
def new(self):
|
|
39
40
|
"""New preset dialog"""
|
|
@@ -63,8 +64,6 @@ class Presets:
|
|
|
63
64
|
self.current_to_preset(id)
|
|
64
65
|
self.window.ui.dialog['create'].close()
|
|
65
66
|
self.update_list()
|
|
66
|
-
self.update_menu()
|
|
67
|
-
|
|
68
67
|
self.toggle(id)
|
|
69
68
|
|
|
70
69
|
def open(self):
|
|
@@ -100,6 +99,8 @@ class Presets:
|
|
|
100
99
|
:param idx: preset index
|
|
101
100
|
"""
|
|
102
101
|
id = self.get_id_by_idx(idx)
|
|
102
|
+
if id is None:
|
|
103
|
+
return
|
|
103
104
|
self.rename(id)
|
|
104
105
|
|
|
105
106
|
def rename(self, id: str):
|
|
@@ -113,7 +114,6 @@ class Presets:
|
|
|
113
114
|
if id in presets:
|
|
114
115
|
name = presets[id]['name']
|
|
115
116
|
|
|
116
|
-
# set dialog and show
|
|
117
117
|
self.window.ui.dialog['rename'].id = 'plugin.preset'
|
|
118
118
|
self.window.ui.dialog['rename'].input.setText(name)
|
|
119
119
|
self.window.ui.dialog['rename'].current = id
|
|
@@ -148,7 +148,6 @@ class Presets:
|
|
|
148
148
|
del presets[id]
|
|
149
149
|
self.store(presets)
|
|
150
150
|
|
|
151
|
-
# remove current preset if exists
|
|
152
151
|
current = self.window.core.config.get('preset.plugins')
|
|
153
152
|
if current == id:
|
|
154
153
|
self.window.core.config.set('preset.plugins', '')
|
|
@@ -166,15 +165,16 @@ class Presets:
|
|
|
166
165
|
self.window.core.plugins.replace_presets(presets)
|
|
167
166
|
self.window.core.plugins.save_presets()
|
|
168
167
|
|
|
169
|
-
def get_id_by_idx(self, idx: int) -> str:
|
|
168
|
+
def get_id_by_idx(self, idx: int) -> Optional[str]:
|
|
170
169
|
"""
|
|
171
170
|
Get preset id by index
|
|
172
171
|
|
|
173
172
|
:param idx: preset index
|
|
174
173
|
"""
|
|
175
174
|
presets = self.get_presets()
|
|
176
|
-
if len(presets)
|
|
175
|
+
if 0 <= idx < len(presets):
|
|
177
176
|
return list(presets.keys())[idx]
|
|
177
|
+
return None
|
|
178
178
|
|
|
179
179
|
def select_by_idx(self, idx: int):
|
|
180
180
|
"""
|
|
@@ -183,8 +183,9 @@ class Presets:
|
|
|
183
183
|
:param idx: preset index
|
|
184
184
|
"""
|
|
185
185
|
id = self.get_id_by_idx(idx)
|
|
186
|
+
if id is None:
|
|
187
|
+
return
|
|
186
188
|
self.toggle(id)
|
|
187
|
-
self.update_menu()
|
|
188
189
|
|
|
189
190
|
def delete_by_idx(
|
|
190
191
|
self,
|
|
@@ -205,6 +206,8 @@ class Presets:
|
|
|
205
206
|
)
|
|
206
207
|
return
|
|
207
208
|
id = self.get_id_by_idx(idx)
|
|
209
|
+
if id is None:
|
|
210
|
+
return
|
|
208
211
|
self.delete(id)
|
|
209
212
|
|
|
210
213
|
def duplicate(self, id: str):
|
|
@@ -214,7 +217,7 @@ class Presets:
|
|
|
214
217
|
:param id: preset ID
|
|
215
218
|
"""
|
|
216
219
|
presets = self.get_presets()
|
|
217
|
-
duplicate =
|
|
220
|
+
duplicate = deepcopy(presets[id])
|
|
218
221
|
new_id = str(uuid4())
|
|
219
222
|
duplicate['name'] = duplicate['name'] + " - copy"
|
|
220
223
|
presets[new_id] = duplicate
|
|
@@ -229,6 +232,8 @@ class Presets:
|
|
|
229
232
|
:param idx: preset index
|
|
230
233
|
"""
|
|
231
234
|
id = self.get_id_by_idx(idx)
|
|
235
|
+
if id is None:
|
|
236
|
+
return
|
|
232
237
|
self.duplicate(id)
|
|
233
238
|
|
|
234
239
|
def reset(self, id: str):
|
|
@@ -265,6 +270,8 @@ class Presets:
|
|
|
265
270
|
)
|
|
266
271
|
return
|
|
267
272
|
id = self.get_id_by_idx(idx)
|
|
273
|
+
if id is None:
|
|
274
|
+
return
|
|
268
275
|
self.reset(id)
|
|
269
276
|
|
|
270
277
|
def get_preset(self, id: str) -> Dict:
|
|
@@ -285,13 +292,10 @@ class Presets:
|
|
|
285
292
|
:return: presets dict
|
|
286
293
|
"""
|
|
287
294
|
presets = self.window.core.plugins.get_presets()
|
|
288
|
-
if not isinstance(presets, dict):
|
|
289
|
-
|
|
290
|
-
return presets
|
|
291
|
-
|
|
292
|
-
# sort by name
|
|
295
|
+
if not isinstance(presets, dict) or not presets:
|
|
296
|
+
return {}
|
|
293
297
|
try:
|
|
294
|
-
return dict(sorted(presets.items(), key=lambda item: item[1]
|
|
298
|
+
return dict(sorted(presets.items(), key=lambda item: item[1].get('name', '')))
|
|
295
299
|
except Exception as e:
|
|
296
300
|
self.window.core.debug.log("Error while sorting presets")
|
|
297
301
|
self.window.core.debug.error(e)
|
|
@@ -305,42 +309,41 @@ class Presets:
|
|
|
305
309
|
def update_menu(self):
|
|
306
310
|
"""Update presets menu"""
|
|
307
311
|
presets = self.get_presets()
|
|
312
|
+
menu_store = self.window.ui.menu
|
|
313
|
+
menu = menu_store['menu.plugins.presets']
|
|
308
314
|
|
|
309
|
-
|
|
310
|
-
for
|
|
311
|
-
|
|
315
|
+
old_actions = list(menu_store['plugins_presets'].values())
|
|
316
|
+
for act in old_actions:
|
|
317
|
+
menu.removeAction(act)
|
|
318
|
+
act.deleteLater()
|
|
319
|
+
menu_store['plugins_presets'].clear()
|
|
312
320
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
self.
|
|
321
|
+
if self._sep_action is not None:
|
|
322
|
+
menu.removeAction(self._sep_action)
|
|
323
|
+
self._sep_action.deleteLater()
|
|
324
|
+
self._sep_action = None
|
|
316
325
|
|
|
317
|
-
# add separator
|
|
318
326
|
if len(presets) > 0:
|
|
319
|
-
self.
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
self.window.ui.menu['plugins_presets'][id].setMenuRole(QAction.MenuRole.NoRole)
|
|
329
|
-
self.window.ui.menu['menu.plugins.presets'].addAction(self.window.ui.menu['plugins_presets'][id])
|
|
330
|
-
|
|
331
|
-
# update current preset
|
|
327
|
+
self._sep_action = menu.addSeparator()
|
|
328
|
+
|
|
329
|
+
for id, preset in presets.items():
|
|
330
|
+
action = QAction(preset['name'], menu, checkable=True)
|
|
331
|
+
action.triggered.connect(lambda checked=False, id=id: self.window.controller.plugins.presets.toggle(id))
|
|
332
|
+
action.setMenuRole(QAction.MenuRole.NoRole)
|
|
333
|
+
menu.addAction(action)
|
|
334
|
+
menu_store['plugins_presets'][id] = action
|
|
335
|
+
|
|
332
336
|
self.update()
|
|
333
337
|
|
|
334
338
|
def update(self):
|
|
335
339
|
"""Update presets menu"""
|
|
336
|
-
|
|
337
|
-
for preset in
|
|
338
|
-
|
|
340
|
+
presets_menu = self.window.ui.menu['plugins_presets']
|
|
341
|
+
for preset in presets_menu:
|
|
342
|
+
presets_menu[preset].setChecked(False)
|
|
339
343
|
|
|
340
|
-
# set checked current preset
|
|
341
344
|
preset = self.window.core.config.get('preset.plugins')
|
|
342
|
-
if preset in
|
|
343
|
-
|
|
345
|
+
if preset in presets_menu:
|
|
346
|
+
presets_menu[preset].setChecked(True)
|
|
344
347
|
|
|
345
348
|
def toggle(self, id: str):
|
|
346
349
|
"""
|
|
@@ -350,13 +353,11 @@ class Presets:
|
|
|
350
353
|
"""
|
|
351
354
|
self.window.core.config.set('preset.plugins', id)
|
|
352
355
|
self.window.core.config.save()
|
|
353
|
-
self.
|
|
356
|
+
self.update()
|
|
354
357
|
|
|
355
|
-
# load preset to current settings
|
|
356
358
|
self.preset_to_current()
|
|
357
|
-
self.window.controller.plugins.reconfigure()
|
|
359
|
+
self.window.controller.plugins.reconfigure()
|
|
358
360
|
|
|
359
|
-
# update status
|
|
360
361
|
preset = self.get_preset(id)
|
|
361
362
|
if preset:
|
|
362
363
|
self.window.update_status("Preset loaded: " + preset['name'])
|
|
@@ -383,12 +384,10 @@ class Presets:
|
|
|
383
384
|
if id:
|
|
384
385
|
preset = self.get_preset(id)
|
|
385
386
|
if preset:
|
|
386
|
-
self.window.core.config.set('plugins_enabled',
|
|
387
|
-
self.window.core.config.set('plugins',
|
|
387
|
+
self.window.core.config.set('plugins_enabled', deepcopy(preset['enabled']))
|
|
388
|
+
self.window.core.config.set('plugins', deepcopy(preset['config']))
|
|
388
389
|
self.window.core.config.save()
|
|
389
|
-
self.window.core.plugins.apply_all_options()
|
|
390
|
-
|
|
391
|
-
# if settings dialog opened then reinitialize
|
|
390
|
+
self.window.core.plugins.apply_all_options()
|
|
392
391
|
if self.window.controller.plugins.settings.config_dialog:
|
|
393
392
|
self.window.controller.plugins.settings.init()
|
|
394
393
|
|
|
@@ -400,8 +399,8 @@ class Presets:
|
|
|
400
399
|
"""
|
|
401
400
|
presets = self.get_presets()
|
|
402
401
|
if preset_id in presets:
|
|
403
|
-
presets[preset_id]['enabled'] =
|
|
404
|
-
presets[preset_id]['config'] =
|
|
402
|
+
presets[preset_id]['enabled'] = deepcopy(self.window.core.config.get('plugins_enabled'))
|
|
403
|
+
presets[preset_id]['config'] = deepcopy(self.window.core.config.get('plugins'))
|
|
405
404
|
self.store(presets)
|
|
406
405
|
self.update_list()
|
|
407
406
|
self.update_menu()
|
|
@@ -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.
|
|
9
|
+
# Updated Date: 2025.08.15 03:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Any
|
|
@@ -32,10 +32,9 @@ class Settings:
|
|
|
32
32
|
def setup(self):
|
|
33
33
|
"""Set up plugin settings"""
|
|
34
34
|
idx = None
|
|
35
|
-
# restore previous selected or restored tab on dialog create
|
|
36
35
|
if 'plugin.settings' in self.window.ui.tabs:
|
|
37
36
|
idx = self.window.ui.tabs['plugin.settings'].currentIndex()
|
|
38
|
-
self.window.plugin_settings.setup(idx)
|
|
37
|
+
self.window.plugin_settings.setup(idx)
|
|
39
38
|
|
|
40
39
|
def toggle_editor(self):
|
|
41
40
|
"""Toggle plugin settings dialog"""
|
|
@@ -49,14 +48,15 @@ class Settings:
|
|
|
49
48
|
if not self.config_initialized:
|
|
50
49
|
self.setup()
|
|
51
50
|
self.config_initialized = True
|
|
52
|
-
if
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
if self.config_dialog:
|
|
52
|
+
return
|
|
53
|
+
self.init()
|
|
54
|
+
self.window.ui.dialogs.open(
|
|
55
|
+
'plugin_settings',
|
|
56
|
+
width=self.width,
|
|
57
|
+
height=self.height
|
|
58
|
+
)
|
|
59
|
+
self.config_dialog = True
|
|
60
60
|
|
|
61
61
|
def open_plugin(self, id: str):
|
|
62
62
|
"""
|
|
@@ -69,20 +69,14 @@ class Settings:
|
|
|
69
69
|
|
|
70
70
|
def init(self):
|
|
71
71
|
"""Initialize plugin settings options"""
|
|
72
|
-
|
|
73
|
-
if self.current_plugin is None:
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
options = plugin.setup() # get plugin options
|
|
81
|
-
|
|
82
|
-
# load and apply options to config dialog
|
|
83
|
-
self.window.controller.config.load_options('plugin.' + id, options)
|
|
84
|
-
|
|
85
|
-
self.window.controller.layout.restore_plugin_settings() # restore previous selected plugin tab
|
|
72
|
+
plugins = self.window.core.plugins.plugins
|
|
73
|
+
if self.current_plugin is None and plugins:
|
|
74
|
+
self.current_plugin = next(iter(plugins))
|
|
75
|
+
cfg = self.window.controller.config
|
|
76
|
+
for pid, plugin in plugins.items():
|
|
77
|
+
options = plugin.setup()
|
|
78
|
+
cfg.load_options(f'plugin.{pid}', options)
|
|
79
|
+
self.window.controller.layout.restore_plugin_settings()
|
|
86
80
|
|
|
87
81
|
def refresh_option(self, id: str, key: str):
|
|
88
82
|
"""
|
|
@@ -91,57 +85,55 @@ class Settings:
|
|
|
91
85
|
:param id: plugin id
|
|
92
86
|
:param key: option key
|
|
93
87
|
"""
|
|
94
|
-
|
|
88
|
+
plugins = self.window.core.plugins.plugins
|
|
89
|
+
plugin = plugins.get(id)
|
|
90
|
+
if not plugin:
|
|
95
91
|
return
|
|
96
|
-
|
|
92
|
+
options = plugin.options
|
|
93
|
+
if key not in options:
|
|
97
94
|
return
|
|
98
|
-
option =
|
|
99
|
-
self.window.controller.config.placeholder.apply(option)
|
|
100
|
-
items = option
|
|
95
|
+
option = options[key]
|
|
96
|
+
self.window.controller.config.placeholder.apply(option)
|
|
97
|
+
items = option.get("keys", {})
|
|
101
98
|
self.window.controller.config.update_list(
|
|
102
99
|
option=option,
|
|
103
|
-
parent_id='plugin.'
|
|
100
|
+
parent_id=f'plugin.{id}',
|
|
104
101
|
key=key,
|
|
105
102
|
items=items,
|
|
106
103
|
)
|
|
107
104
|
|
|
108
105
|
def save(self):
|
|
109
106
|
"""Save plugin settings"""
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
for key in options:
|
|
120
|
-
value =
|
|
121
|
-
parent_id='plugin.'
|
|
122
|
-
key=key,
|
|
123
|
-
option=
|
|
107
|
+
window = self.window
|
|
108
|
+
plugins = window.core.plugins.plugins
|
|
109
|
+
controller_cfg = window.controller.config
|
|
110
|
+
config_data = window.core.config.data
|
|
111
|
+
plugins_cfg = config_data.setdefault('plugins', {})
|
|
112
|
+
|
|
113
|
+
for pid, plugin in plugins.items():
|
|
114
|
+
options = plugin.setup()
|
|
115
|
+
dst = plugins_cfg.setdefault(pid, {})
|
|
116
|
+
for key, opt in options.items():
|
|
117
|
+
value = controller_cfg.get_value(
|
|
118
|
+
parent_id=f'plugin.{pid}',
|
|
119
|
+
key=key,
|
|
120
|
+
option=opt,
|
|
124
121
|
)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# remove key from config if plugin option not exists
|
|
129
|
-
for key in list(self.window.core.config.data['plugins'].keys()):
|
|
130
|
-
if key not in self.window.core.plugins.plugins:
|
|
131
|
-
self.window.core.config.data['plugins'].pop(key)
|
|
122
|
+
plugin.options[key]['value'] = value
|
|
123
|
+
dst[key] = value
|
|
132
124
|
|
|
133
|
-
|
|
134
|
-
|
|
125
|
+
stale = set(plugins_cfg.keys()) - set(plugins.keys())
|
|
126
|
+
for pid in stale:
|
|
127
|
+
plugins_cfg.pop(pid, None)
|
|
135
128
|
|
|
136
|
-
|
|
137
|
-
|
|
129
|
+
window.controller.plugins.presets.save_current()
|
|
130
|
+
window.core.config.save()
|
|
138
131
|
self.close()
|
|
139
|
-
|
|
132
|
+
window.update_status(trans('info.settings.saved'))
|
|
140
133
|
|
|
141
|
-
# dispatch on update event
|
|
142
134
|
event = Event(Event.PLUGIN_SETTINGS_CHANGED)
|
|
143
|
-
|
|
144
|
-
|
|
135
|
+
window.dispatch(event)
|
|
136
|
+
window.controller.ui.update_tokens()
|
|
145
137
|
|
|
146
138
|
def close(self):
|
|
147
139
|
"""Close plugin settings dialog"""
|
|
@@ -157,15 +149,12 @@ class Settings:
|
|
|
157
149
|
"""
|
|
158
150
|
if not force:
|
|
159
151
|
self.window.ui.dialogs.confirm(
|
|
160
|
-
type='plugin.settings.defaults.user',
|
|
152
|
+
type='plugin.settings.defaults.user',
|
|
161
153
|
id=-1,
|
|
162
154
|
msg=trans('dialog.plugin.settings.defaults.user.confirm'),
|
|
163
155
|
)
|
|
164
156
|
return
|
|
165
|
-
|
|
166
|
-
# reload settings window
|
|
167
157
|
self.init()
|
|
168
|
-
# self.window.ui.dialogs.alert(trans('dialog.plugin.settings.defaults.user.result'))
|
|
169
158
|
|
|
170
159
|
def load_defaults_app(self, force: bool = False):
|
|
171
160
|
"""
|
|
@@ -180,11 +169,7 @@ class Settings:
|
|
|
180
169
|
msg=trans('dialog.plugin.settings.defaults.app.confirm'),
|
|
181
170
|
)
|
|
182
171
|
return
|
|
183
|
-
|
|
184
|
-
# restore default options
|
|
185
172
|
self.window.core.plugins.restore_options(self.current_plugin)
|
|
186
|
-
|
|
187
|
-
# reload settings window
|
|
188
173
|
self.init()
|
|
189
174
|
self.window.ui.dialogs.alert(trans('dialog.plugin.settings.defaults.app.result'))
|
|
190
175
|
|
|
@@ -196,4 +181,4 @@ class Settings:
|
|
|
196
181
|
:param key: option key
|
|
197
182
|
:return: option value
|
|
198
183
|
"""
|
|
199
|
-
return self.window.core.plugins.plugins[id].options[key]
|
|
184
|
+
return self.window.core.plugins.plugins[id].options[key]
|
|
@@ -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.08.14
|
|
9
|
+
# Updated Date: 2025.08.14 13:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import datetime
|
|
@@ -38,6 +38,14 @@ from pygpt_net.utils import trans
|
|
|
38
38
|
from .experts import Experts
|
|
39
39
|
|
|
40
40
|
class Editor:
|
|
41
|
+
|
|
42
|
+
TAB_IDX = {
|
|
43
|
+
"general": 0,
|
|
44
|
+
"personalize": 1,
|
|
45
|
+
"experts": 2,
|
|
46
|
+
"remote_tools": 3,
|
|
47
|
+
}
|
|
48
|
+
|
|
41
49
|
def __init__(self, window=None):
|
|
42
50
|
"""
|
|
43
51
|
Presets editor controller
|
|
@@ -77,7 +85,7 @@ class Editor:
|
|
|
77
85
|
"label": "preset.user_name",
|
|
78
86
|
},
|
|
79
87
|
"description": {
|
|
80
|
-
"type": "
|
|
88
|
+
"type": "text",
|
|
81
89
|
"label": "preset.description",
|
|
82
90
|
"placeholder": "preset.description.desc",
|
|
83
91
|
},
|
|
@@ -189,25 +197,6 @@ class Editor:
|
|
|
189
197
|
},
|
|
190
198
|
}
|
|
191
199
|
},
|
|
192
|
-
"assistant_id": {
|
|
193
|
-
"type": "text",
|
|
194
|
-
"label": "preset.assistant_id",
|
|
195
|
-
"description": "preset.assistant_id.desc",
|
|
196
|
-
},
|
|
197
|
-
"tool.function": {
|
|
198
|
-
"type": "dict",
|
|
199
|
-
"label": "preset.tool.function",
|
|
200
|
-
"keys": {
|
|
201
|
-
'name': 'text',
|
|
202
|
-
'params': 'textarea',
|
|
203
|
-
'desc': 'textarea',
|
|
204
|
-
},
|
|
205
|
-
"extra": {
|
|
206
|
-
"urls": {
|
|
207
|
-
"Help": "https://platform.openai.com/docs/guides/function-calling",
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
200
|
}
|
|
212
201
|
self.hidden_by_mode = { # hidden fields by mode
|
|
213
202
|
MODE_CHAT: ["idx"],
|
|
@@ -268,15 +257,6 @@ class Editor:
|
|
|
268
257
|
self.window.ui.add_hook("update.preset.agent_provider", self.hook_update)
|
|
269
258
|
self.window.ui.add_hook("update.preset.agent_provider_openai", self.hook_update)
|
|
270
259
|
|
|
271
|
-
# register functions dictionary
|
|
272
|
-
parent = "preset"
|
|
273
|
-
key = "tool.function"
|
|
274
|
-
self.window.ui.dialogs.register_dictionary(
|
|
275
|
-
key,
|
|
276
|
-
parent,
|
|
277
|
-
self.get_option(key),
|
|
278
|
-
)
|
|
279
|
-
|
|
280
260
|
def toggle_extra_options(self):
|
|
281
261
|
"""
|
|
282
262
|
Toggle extra options in preset editor
|
|
@@ -594,6 +574,7 @@ class Editor:
|
|
|
594
574
|
checkboxLayout.addLayout(opt_layout)
|
|
595
575
|
else:
|
|
596
576
|
layout.addLayout(opt_layout)
|
|
577
|
+
layout.addStretch(1)
|
|
597
578
|
layout.addLayout(checkboxLayout)
|
|
598
579
|
|
|
599
580
|
# as tab
|
|
@@ -777,6 +758,7 @@ class Editor:
|
|
|
777
758
|
# load extra options
|
|
778
759
|
self.load_extra_options(data)
|
|
779
760
|
|
|
761
|
+
# toggle extra options
|
|
780
762
|
self.toggle_extra_options()
|
|
781
763
|
|
|
782
764
|
# update experts list, after ID loaded
|
|
@@ -785,24 +767,6 @@ class Editor:
|
|
|
785
767
|
# setup avatar config
|
|
786
768
|
self.update_avatar_config(data)
|
|
787
769
|
|
|
788
|
-
# restore functions
|
|
789
|
-
if data.has_functions():
|
|
790
|
-
functions = data.get_functions()
|
|
791
|
-
values = []
|
|
792
|
-
for function in functions:
|
|
793
|
-
values.append(
|
|
794
|
-
{
|
|
795
|
-
"name": function['name'],
|
|
796
|
-
"params": function['params'],
|
|
797
|
-
"desc": function['desc'],
|
|
798
|
-
}
|
|
799
|
-
)
|
|
800
|
-
self.window.ui.config[self.id]['tool.function'].items = values
|
|
801
|
-
self.window.ui.config[self.id]['tool.function'].model.updateData(values)
|
|
802
|
-
else:
|
|
803
|
-
self.window.ui.config[self.id]['tool.function'].items = []
|
|
804
|
-
self.window.ui.config[self.id]['tool.function'].model.updateData([])
|
|
805
|
-
|
|
806
770
|
# set focus to name field
|
|
807
771
|
current_model = self.window.core.config.get('model')
|
|
808
772
|
# set current model in combo box as selected
|
|
@@ -954,16 +918,9 @@ class Editor:
|
|
|
954
918
|
# sort by name
|
|
955
919
|
self.window.core.presets.sort_by_name()
|
|
956
920
|
|
|
957
|
-
# switch to editing preset
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
self.window.controller.presets.select_model()
|
|
961
|
-
else:
|
|
962
|
-
# switch to model if current preset
|
|
963
|
-
current_preset = self.window.core.config.get('preset')
|
|
964
|
-
if current_preset is not None and current_preset == id:
|
|
965
|
-
self.window.controller.presets.set(mode, current_preset)
|
|
966
|
-
self.window.controller.presets.select_model()
|
|
921
|
+
# switch to editing preset on save
|
|
922
|
+
self.window.controller.presets.set(mode, id)
|
|
923
|
+
self.window.controller.presets.select_model()
|
|
967
924
|
|
|
968
925
|
# update presets list
|
|
969
926
|
no_scroll = False
|
|
@@ -1000,36 +957,6 @@ class Editor:
|
|
|
1000
957
|
'function': [], # functions are assigned separately (below)
|
|
1001
958
|
}
|
|
1002
959
|
|
|
1003
|
-
# assign functions tool
|
|
1004
|
-
values = self.window.controller.config.get_value(
|
|
1005
|
-
parent_id=self.id,
|
|
1006
|
-
key='tool.function',
|
|
1007
|
-
option=self.options['tool.function'],
|
|
1008
|
-
)
|
|
1009
|
-
functions = []
|
|
1010
|
-
for function in values:
|
|
1011
|
-
name = function['name']
|
|
1012
|
-
params = function['params']
|
|
1013
|
-
desc = function['desc']
|
|
1014
|
-
if name is None or name == "":
|
|
1015
|
-
continue
|
|
1016
|
-
if params is None or params == "":
|
|
1017
|
-
params = '{"type": "object", "properties": {}}' # default empty JSON params
|
|
1018
|
-
if desc is None:
|
|
1019
|
-
desc = ""
|
|
1020
|
-
functions.append(
|
|
1021
|
-
{
|
|
1022
|
-
"name": name,
|
|
1023
|
-
"params": params,
|
|
1024
|
-
"desc": desc,
|
|
1025
|
-
}
|
|
1026
|
-
)
|
|
1027
|
-
|
|
1028
|
-
if len(functions) > 0:
|
|
1029
|
-
preset.tools['function'] = functions
|
|
1030
|
-
else:
|
|
1031
|
-
preset.tools['function'] = []
|
|
1032
|
-
|
|
1033
960
|
# extra options
|
|
1034
961
|
self.append_extra_options(preset)
|
|
1035
962
|
|
|
@@ -1189,3 +1116,21 @@ class Editor:
|
|
|
1189
1116
|
option=self.options["ai_avatar"],
|
|
1190
1117
|
value="",
|
|
1191
1118
|
)
|
|
1119
|
+
|
|
1120
|
+
def toggle_tab(self, name: str, show: bool = True):
|
|
1121
|
+
"""
|
|
1122
|
+
Show experts tab
|
|
1123
|
+
|
|
1124
|
+
:param name: name of the tab
|
|
1125
|
+
:param show: Show or hide experts tab
|
|
1126
|
+
"""
|
|
1127
|
+
tabs = self.window.ui.tabs['preset.editor.tabs']
|
|
1128
|
+
idx = self.TAB_IDX[name]
|
|
1129
|
+
if tabs is not None:
|
|
1130
|
+
if show:
|
|
1131
|
+
tabs.setTabEnabled(idx, True)
|
|
1132
|
+
tabs.setTabVisible(idx, True)
|
|
1133
|
+
self.experts.update_tab()
|
|
1134
|
+
else:
|
|
1135
|
+
tabs.setTabEnabled(idx, False)
|
|
1136
|
+
tabs.setTabVisible(idx, False)
|
|
@@ -6,12 +6,14 @@
|
|
|
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.08.
|
|
9
|
+
# Updated Date: 2025.08.14 13:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from pygpt_net.core.types import (
|
|
13
13
|
MODE_EXPERT,
|
|
14
14
|
)
|
|
15
|
+
from pygpt_net.utils import trans
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
class Experts:
|
|
17
19
|
def __init__(self, window=None):
|
|
@@ -74,6 +76,8 @@ class Experts:
|
|
|
74
76
|
# clear selected list if no agent is selected
|
|
75
77
|
self.window.ui.nodes['preset.editor.experts'].update_selected({})
|
|
76
78
|
|
|
79
|
+
self.update_tab()
|
|
80
|
+
|
|
77
81
|
def change_available(self):
|
|
78
82
|
"""Change selected expert"""
|
|
79
83
|
pass
|
|
@@ -157,3 +161,18 @@ class Experts:
|
|
|
157
161
|
self.window.core.presets.remove_expert(agent_uuid, expert_uuid)
|
|
158
162
|
self.update_list()
|
|
159
163
|
|
|
164
|
+
def update_tab(self):
|
|
165
|
+
"""Update experts tab label with number of experts"""
|
|
166
|
+
num = 0
|
|
167
|
+
agent_uuid = self.get_current_agent_id()
|
|
168
|
+
if agent_uuid:
|
|
169
|
+
agent = self.window.core.presets.get_by_uuid(agent_uuid)
|
|
170
|
+
if agent:
|
|
171
|
+
num = len(agent.experts)
|
|
172
|
+
tabs = self.window.ui.tabs['preset.editor.tabs']
|
|
173
|
+
idx = self.window.controller.presets.editor.TAB_IDX["experts"]
|
|
174
|
+
if num == 0:
|
|
175
|
+
tabs.setTabText(idx, trans("preset.tab.experts"))
|
|
176
|
+
else:
|
|
177
|
+
tabs.setTabText(idx, trans("preset.tab.experts") + f" ({num})")
|
|
178
|
+
|