pygpt-net 2.6.20__py3-none-any.whl → 2.6.22__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 +13 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +3 -1
- pygpt_net/controller/__init__.py +4 -8
- pygpt_net/controller/access/voice.py +2 -2
- pygpt_net/controller/agent/agent.py +130 -2
- pygpt_net/controller/agent/experts.py +93 -96
- pygpt_net/controller/agent/llama.py +2 -1
- pygpt_net/controller/assistant/assistant.py +18 -1
- pygpt_net/controller/assistant/batch.py +2 -3
- pygpt_net/controller/assistant/editor.py +2 -2
- pygpt_net/controller/assistant/files.py +2 -3
- pygpt_net/controller/assistant/store.py +2 -2
- pygpt_net/controller/attachment/attachment.py +17 -1
- pygpt_net/controller/audio/audio.py +2 -2
- pygpt_net/controller/camera/camera.py +15 -7
- pygpt_net/controller/chat/chat.py +2 -2
- pygpt_net/controller/chat/common.py +50 -33
- pygpt_net/controller/chat/image.py +67 -77
- pygpt_net/controller/chat/input.py +94 -166
- pygpt_net/controller/chat/output.py +83 -140
- pygpt_net/controller/chat/response.py +83 -102
- pygpt_net/controller/chat/text.py +116 -149
- pygpt_net/controller/ctx/common.py +2 -1
- pygpt_net/controller/ctx/ctx.py +87 -6
- pygpt_net/controller/files/files.py +13 -1
- pygpt_net/controller/idx/idx.py +26 -2
- pygpt_net/controller/idx/indexer.py +85 -76
- pygpt_net/controller/kernel/reply.py +53 -66
- pygpt_net/controller/kernel/stack.py +16 -16
- pygpt_net/controller/lang/lang.py +52 -34
- pygpt_net/controller/model/importer.py +3 -2
- pygpt_net/controller/model/model.py +62 -3
- pygpt_net/controller/notepad/notepad.py +86 -84
- pygpt_net/controller/plugins/settings.py +3 -4
- pygpt_net/controller/settings/editor.py +4 -4
- pygpt_net/controller/settings/profile.py +105 -124
- pygpt_net/controller/theme/menu.py +154 -57
- pygpt_net/controller/theme/nodes.py +51 -44
- pygpt_net/controller/theme/theme.py +33 -9
- pygpt_net/controller/tools/tools.py +2 -2
- pygpt_net/controller/ui/tabs.py +2 -3
- pygpt_net/controller/ui/ui.py +16 -2
- pygpt_net/core/agents/observer/evaluation.py +3 -3
- pygpt_net/core/agents/provider.py +25 -3
- pygpt_net/core/agents/runner.py +4 -1
- pygpt_net/core/agents/runners/llama_workflow.py +19 -7
- pygpt_net/core/agents/runners/loop.py +3 -1
- pygpt_net/core/agents/runners/openai_workflow.py +17 -3
- pygpt_net/core/agents/tools.py +4 -1
- pygpt_net/core/bridge/context.py +34 -37
- pygpt_net/core/ctx/container.py +13 -12
- pygpt_net/core/ctx/ctx.py +1 -1
- pygpt_net/core/ctx/output.py +7 -4
- pygpt_net/core/db/database.py +2 -2
- pygpt_net/core/debug/console/console.py +2 -2
- pygpt_net/core/debug/debug.py +12 -1
- pygpt_net/core/dispatcher/dispatcher.py +24 -1
- pygpt_net/core/events/app.py +7 -7
- pygpt_net/core/events/control.py +26 -26
- pygpt_net/core/events/event.py +6 -3
- pygpt_net/core/events/kernel.py +2 -2
- pygpt_net/core/events/render.py +13 -13
- pygpt_net/core/experts/experts.py +76 -82
- pygpt_net/core/experts/worker.py +12 -12
- pygpt_net/core/filesystem/actions.py +1 -2
- pygpt_net/core/models/models.py +5 -1
- pygpt_net/core/models/ollama.py +14 -5
- pygpt_net/core/render/plain/helpers.py +2 -5
- pygpt_net/core/render/plain/renderer.py +26 -30
- pygpt_net/core/render/web/body.py +1 -1
- pygpt_net/core/render/web/helpers.py +2 -2
- pygpt_net/core/render/web/renderer.py +4 -4
- pygpt_net/core/settings/settings.py +43 -13
- pygpt_net/core/tabs/tabs.py +20 -13
- pygpt_net/core/types/__init__.py +2 -1
- pygpt_net/core/types/agent.py +4 -4
- pygpt_net/core/types/base.py +19 -0
- pygpt_net/core/types/console.py +6 -6
- pygpt_net/core/types/mode.py +8 -8
- pygpt_net/core/types/multimodal.py +3 -3
- pygpt_net/core/types/openai.py +2 -1
- pygpt_net/data/config/config.json +5 -5
- pygpt_net/data/config/models.json +19 -3
- pygpt_net/data/config/settings.json +14 -14
- pygpt_net/data/locale/locale.de.ini +4 -1
- pygpt_net/data/locale/locale.en.ini +6 -3
- pygpt_net/data/locale/locale.es.ini +4 -1
- pygpt_net/data/locale/locale.fr.ini +4 -1
- pygpt_net/data/locale/locale.it.ini +4 -1
- pygpt_net/data/locale/locale.pl.ini +5 -4
- pygpt_net/data/locale/locale.uk.ini +4 -1
- pygpt_net/data/locale/locale.zh.ini +4 -1
- pygpt_net/item/ctx.py +256 -240
- pygpt_net/item/model.py +59 -116
- pygpt_net/item/preset.py +122 -105
- pygpt_net/plugin/twitter/plugin.py +2 -2
- pygpt_net/provider/agents/llama_index/workflow/planner.py +3 -3
- pygpt_net/provider/agents/openai/agent.py +4 -12
- pygpt_net/provider/agents/openai/agent_b2b.py +10 -15
- pygpt_net/provider/agents/openai/agent_planner.py +4 -4
- pygpt_net/provider/agents/openai/agent_with_experts.py +3 -7
- pygpt_net/provider/agents/openai/agent_with_experts_feedback.py +4 -8
- pygpt_net/provider/agents/openai/agent_with_feedback.py +4 -8
- pygpt_net/provider/agents/openai/bot_researcher.py +2 -18
- pygpt_net/provider/agents/openai/bots/__init__.py +0 -0
- pygpt_net/provider/agents/openai/bots/research_bot/__init__.py +0 -0
- pygpt_net/provider/agents/openai/bots/research_bot/agents/__init__.py +0 -0
- pygpt_net/provider/agents/openai/bots/research_bot/agents/planner_agent.py +1 -1
- pygpt_net/provider/agents/openai/bots/research_bot/agents/search_agent.py +1 -0
- pygpt_net/provider/agents/openai/bots/research_bot/agents/writer_agent.py +1 -1
- pygpt_net/provider/agents/openai/bots/research_bot/manager.py +1 -10
- pygpt_net/provider/agents/openai/evolve.py +5 -9
- pygpt_net/provider/agents/openai/supervisor.py +4 -8
- pygpt_net/provider/core/config/patch.py +10 -3
- pygpt_net/provider/core/ctx/db_sqlite/utils.py +43 -43
- pygpt_net/provider/core/model/patch.py +11 -1
- pygpt_net/provider/core/preset/json_file.py +47 -49
- pygpt_net/provider/gpt/agents/experts.py +2 -2
- pygpt_net/tools/audio_transcriber/ui/dialogs.py +44 -54
- pygpt_net/tools/code_interpreter/body.py +1 -2
- pygpt_net/tools/code_interpreter/tool.py +7 -4
- pygpt_net/tools/code_interpreter/ui/html.py +1 -3
- pygpt_net/tools/code_interpreter/ui/widgets.py +2 -3
- pygpt_net/tools/html_canvas/ui/widgets.py +1 -3
- pygpt_net/tools/image_viewer/ui/dialogs.py +40 -37
- pygpt_net/tools/indexer/ui/widgets.py +2 -4
- pygpt_net/tools/media_player/tool.py +2 -5
- pygpt_net/tools/media_player/ui/widgets.py +60 -36
- pygpt_net/tools/text_editor/ui/widgets.py +18 -19
- pygpt_net/tools/translator/ui/widgets.py +39 -35
- pygpt_net/ui/base/context_menu.py +9 -4
- pygpt_net/ui/dialog/db.py +1 -3
- pygpt_net/ui/dialog/models.py +1 -3
- pygpt_net/ui/dialog/models_importer.py +2 -4
- pygpt_net/ui/dialogs.py +34 -30
- pygpt_net/ui/layout/chat/attachments.py +72 -84
- pygpt_net/ui/layout/chat/attachments_ctx.py +40 -44
- pygpt_net/ui/layout/chat/attachments_uploaded.py +36 -39
- pygpt_net/ui/layout/chat/calendar.py +100 -70
- pygpt_net/ui/layout/chat/chat.py +23 -17
- pygpt_net/ui/layout/chat/input.py +95 -118
- pygpt_net/ui/layout/chat/output.py +100 -162
- pygpt_net/ui/layout/chat/painter.py +89 -61
- pygpt_net/ui/layout/ctx/ctx_list.py +43 -52
- pygpt_net/ui/layout/status.py +23 -14
- pygpt_net/ui/layout/toolbox/agent.py +27 -38
- pygpt_net/ui/layout/toolbox/agent_llama.py +42 -45
- pygpt_net/ui/layout/toolbox/assistants.py +42 -38
- pygpt_net/ui/layout/toolbox/computer_env.py +32 -23
- pygpt_net/ui/layout/toolbox/footer.py +13 -16
- pygpt_net/ui/layout/toolbox/image.py +18 -21
- pygpt_net/ui/layout/toolbox/indexes.py +46 -89
- pygpt_net/ui/layout/toolbox/mode.py +20 -7
- pygpt_net/ui/layout/toolbox/model.py +12 -10
- pygpt_net/ui/layout/toolbox/presets.py +68 -52
- pygpt_net/ui/layout/toolbox/prompt.py +31 -58
- pygpt_net/ui/layout/toolbox/toolbox.py +25 -21
- pygpt_net/ui/layout/toolbox/vision.py +20 -22
- pygpt_net/ui/main.py +2 -4
- pygpt_net/ui/menu/about.py +64 -84
- pygpt_net/ui/menu/audio.py +87 -63
- pygpt_net/ui/menu/config.py +121 -127
- pygpt_net/ui/menu/debug.py +69 -76
- pygpt_net/ui/menu/file.py +32 -35
- pygpt_net/ui/menu/menu.py +2 -3
- pygpt_net/ui/menu/plugins.py +69 -33
- pygpt_net/ui/menu/theme.py +45 -46
- pygpt_net/ui/menu/tools.py +56 -60
- pygpt_net/ui/menu/video.py +20 -25
- pygpt_net/ui/tray.py +1 -2
- pygpt_net/ui/widget/audio/bar.py +1 -3
- pygpt_net/ui/widget/audio/input_button.py +3 -4
- pygpt_net/ui/widget/calendar/select.py +1 -2
- pygpt_net/ui/widget/dialog/base.py +12 -9
- pygpt_net/ui/widget/dialog/editor_file.py +20 -23
- pygpt_net/ui/widget/dialog/find.py +25 -24
- pygpt_net/ui/widget/dialog/profile.py +57 -53
- pygpt_net/ui/widget/draw/painter.py +62 -93
- pygpt_net/ui/widget/element/button.py +42 -30
- pygpt_net/ui/widget/element/checkbox.py +23 -15
- pygpt_net/ui/widget/element/group.py +6 -5
- pygpt_net/ui/widget/element/labels.py +1 -2
- pygpt_net/ui/widget/filesystem/explorer.py +93 -102
- pygpt_net/ui/widget/image/display.py +1 -2
- pygpt_net/ui/widget/lists/assistant.py +1 -2
- pygpt_net/ui/widget/lists/attachment.py +1 -2
- pygpt_net/ui/widget/lists/attachment_ctx.py +1 -2
- pygpt_net/ui/widget/lists/context.py +2 -4
- pygpt_net/ui/widget/lists/index.py +1 -2
- pygpt_net/ui/widget/lists/model.py +1 -2
- pygpt_net/ui/widget/lists/model_editor.py +1 -2
- pygpt_net/ui/widget/lists/model_importer.py +1 -2
- pygpt_net/ui/widget/lists/preset.py +1 -2
- pygpt_net/ui/widget/lists/preset_plugins.py +1 -2
- pygpt_net/ui/widget/lists/profile.py +1 -2
- pygpt_net/ui/widget/lists/uploaded.py +1 -2
- pygpt_net/ui/widget/option/checkbox.py +2 -4
- pygpt_net/ui/widget/option/checkbox_list.py +1 -4
- pygpt_net/ui/widget/option/cmd.py +1 -4
- pygpt_net/ui/widget/option/dictionary.py +25 -28
- pygpt_net/ui/widget/option/input.py +1 -3
- pygpt_net/ui/widget/tabs/Input.py +16 -12
- pygpt_net/ui/widget/tabs/body.py +5 -3
- pygpt_net/ui/widget/tabs/layout.py +36 -25
- pygpt_net/ui/widget/tabs/output.py +96 -74
- pygpt_net/ui/widget/textarea/calendar_note.py +1 -2
- pygpt_net/ui/widget/textarea/editor.py +41 -73
- pygpt_net/ui/widget/textarea/find.py +11 -10
- pygpt_net/ui/widget/textarea/html.py +3 -6
- pygpt_net/ui/widget/textarea/input.py +63 -64
- pygpt_net/ui/widget/textarea/notepad.py +54 -38
- pygpt_net/ui/widget/textarea/output.py +65 -54
- pygpt_net/ui/widget/textarea/search_input.py +5 -4
- pygpt_net/ui/widget/textarea/web.py +2 -4
- pygpt_net/ui/widget/vision/camera.py +2 -31
- {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/METADATA +25 -154
- {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/RECORD +218 -217
- {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.20.dist-info → pygpt_net-2.6.22.dist-info}/entry_points.txt +0 -0
|
@@ -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:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from pygpt_net.core.events import RenderEvent
|
|
@@ -28,24 +28,33 @@ class Nodes:
|
|
|
28
28
|
:param key: UI node key
|
|
29
29
|
:param type: stylesheet type
|
|
30
30
|
"""
|
|
31
|
-
|
|
31
|
+
nodes = self.window.ui.nodes
|
|
32
|
+
theme = self.window.controller.theme
|
|
33
|
+
|
|
34
|
+
if key not in nodes:
|
|
32
35
|
return
|
|
33
36
|
|
|
34
37
|
if type == 'font.toolbox':
|
|
35
|
-
|
|
38
|
+
nodes[key].setStyleSheet(theme.style('font.toolbox'))
|
|
36
39
|
elif type == 'font.chat.output':
|
|
37
|
-
|
|
40
|
+
style_output = theme.style('font.chat.output')
|
|
41
|
+
for pid in nodes[key]:
|
|
38
42
|
try:
|
|
39
|
-
|
|
43
|
+
nodes[key][pid].setStyleSheet(style_output)
|
|
40
44
|
except Exception as e:
|
|
41
45
|
pass
|
|
42
46
|
elif type == 'font.chat.input':
|
|
43
|
-
|
|
47
|
+
nodes[key].setStyleSheet(theme.style('font.chat.input'))
|
|
44
48
|
elif type == 'font.ctx.list':
|
|
45
|
-
|
|
49
|
+
nodes[key].setStyleSheet(theme.style('font.ctx.list'))
|
|
46
50
|
|
|
47
51
|
def apply_all(self):
|
|
48
52
|
"""Apply stylesheets to nodes"""
|
|
53
|
+
w = self.window
|
|
54
|
+
ui = w.ui
|
|
55
|
+
ctrl = w.controller
|
|
56
|
+
engine = ctrl.chat.render.get_engine()
|
|
57
|
+
|
|
49
58
|
nodes = {
|
|
50
59
|
'font.chat.input': [
|
|
51
60
|
'input',
|
|
@@ -90,58 +99,56 @@ class Nodes:
|
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
# apply to nodes
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
apply_ref = self.apply
|
|
103
|
+
skip_output = engine != 'legacy'
|
|
104
|
+
for t, keys in nodes.items():
|
|
105
|
+
for k in keys:
|
|
106
|
+
if skip_output and k == "output":
|
|
96
107
|
continue
|
|
97
|
-
|
|
108
|
+
apply_ref(k, t)
|
|
98
109
|
|
|
99
110
|
# apply to notepads
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
111
|
+
size = w.core.config.get('font_size')
|
|
112
|
+
style_output = ctrl.theme.style('font.chat.output')
|
|
113
|
+
if ui.notepad:
|
|
114
|
+
for np in ui.notepad.values():
|
|
115
|
+
ta = np.textarea
|
|
116
|
+
ta.setStyleSheet(style_output)
|
|
117
|
+
ta.value = size
|
|
104
118
|
|
|
105
119
|
# apply to calendar
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
size = self.window.core.config.get('font_size')
|
|
111
|
-
if 'note' in self.window.ui.calendar:
|
|
112
|
-
self.window.ui.calendar['note'].value = size
|
|
113
|
-
if num_notepads > 0:
|
|
114
|
-
for id in range(1, num_notepads + 1):
|
|
115
|
-
if id in self.window.ui.notepad:
|
|
116
|
-
self.window.ui.notepad[id].textarea.value = size
|
|
120
|
+
note = ui.calendar.get('note')
|
|
121
|
+
if note is not None:
|
|
122
|
+
note.setStyleSheet(style_output)
|
|
123
|
+
note.value = size
|
|
117
124
|
|
|
118
125
|
# plain text/markdown
|
|
119
|
-
|
|
126
|
+
output_plain = ui.nodes.get('output_plain', {})
|
|
127
|
+
for obj in output_plain.values():
|
|
120
128
|
try:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
except Exception
|
|
129
|
+
obj.value = size
|
|
130
|
+
obj.update()
|
|
131
|
+
except Exception:
|
|
124
132
|
pass
|
|
125
133
|
|
|
126
134
|
# ------------------------
|
|
127
135
|
|
|
128
136
|
# zoom, (Chromium, web engine)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
output_nodes = ui.nodes.get('output', {})
|
|
138
|
+
if engine == 'web':
|
|
139
|
+
zoom = w.core.config.get('zoom')
|
|
140
|
+
for obj in output_nodes.values():
|
|
132
141
|
try:
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
except Exception
|
|
142
|
+
obj.value = zoom
|
|
143
|
+
obj.update_zoom()
|
|
144
|
+
except Exception:
|
|
136
145
|
pass
|
|
137
|
-
|
|
138
|
-
self.window.dispatch(event)
|
|
146
|
+
w.dispatch(RenderEvent(RenderEvent.ON_THEME_CHANGE))
|
|
139
147
|
|
|
140
148
|
# font size, legacy (markdown)
|
|
141
|
-
elif
|
|
142
|
-
for
|
|
143
|
-
|
|
144
|
-
|
|
149
|
+
elif engine == 'legacy':
|
|
150
|
+
for obj in output_nodes.values():
|
|
151
|
+
obj.value = size
|
|
152
|
+
obj.update()
|
|
145
153
|
|
|
146
|
-
# update tools
|
|
147
|
-
self.window.tools.setup_theme()
|
|
154
|
+
w.tools.setup_theme() # update tools
|
|
@@ -6,13 +6,16 @@
|
|
|
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.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
13
13
|
from typing import Any, Optional
|
|
14
14
|
|
|
15
|
+
from PySide6.QtWidgets import QApplication
|
|
16
|
+
|
|
15
17
|
from pygpt_net.core.events import RenderEvent
|
|
18
|
+
from pygpt_net.utils import trans
|
|
16
19
|
|
|
17
20
|
from .common import Common
|
|
18
21
|
from .markdown import Markdown
|
|
@@ -41,6 +44,29 @@ class Theme:
|
|
|
41
44
|
self.common.toggle_tooltips()
|
|
42
45
|
self.reload(force=False)
|
|
43
46
|
|
|
47
|
+
def toggle_theme_by_menu(self, name):
|
|
48
|
+
"""
|
|
49
|
+
Toggle theme by menu action
|
|
50
|
+
|
|
51
|
+
:param name: theme name
|
|
52
|
+
"""
|
|
53
|
+
self.window.update_status(trans("status.loading"))
|
|
54
|
+
QApplication.processEvents()
|
|
55
|
+
self.toggle(name, force=True)
|
|
56
|
+
self.window.update_status("")
|
|
57
|
+
|
|
58
|
+
def toggle_option_by_menu(self, name: str, value: Any = None):
|
|
59
|
+
"""
|
|
60
|
+
Toggle theme option by menu action
|
|
61
|
+
|
|
62
|
+
:param name: option name
|
|
63
|
+
:param value: option value
|
|
64
|
+
"""
|
|
65
|
+
self.window.update_status(trans("status.loading"))
|
|
66
|
+
QApplication.processEvents()
|
|
67
|
+
self.toggle_option(name, value)
|
|
68
|
+
self.window.update_status("")
|
|
69
|
+
|
|
44
70
|
def toggle(
|
|
45
71
|
self,
|
|
46
72
|
name: str,
|
|
@@ -85,6 +111,7 @@ class Theme:
|
|
|
85
111
|
|
|
86
112
|
:param name: web style name
|
|
87
113
|
"""
|
|
114
|
+
QApplication.processEvents()
|
|
88
115
|
core = self.window.core
|
|
89
116
|
core.config.set('theme.style', name)
|
|
90
117
|
core.config.save()
|
|
@@ -103,6 +130,7 @@ class Theme:
|
|
|
103
130
|
:param name: option name
|
|
104
131
|
:param value: option value
|
|
105
132
|
"""
|
|
133
|
+
QApplication.processEvents()
|
|
106
134
|
window = self.window
|
|
107
135
|
core = window.core
|
|
108
136
|
cfg = core.config
|
|
@@ -149,8 +177,7 @@ class Theme:
|
|
|
149
177
|
|
|
150
178
|
def update_style(self):
|
|
151
179
|
"""Update style"""
|
|
152
|
-
|
|
153
|
-
self.toggle_style(current)
|
|
180
|
+
self.toggle_style(self.window.core.config.get('theme.style'))
|
|
154
181
|
|
|
155
182
|
def update_theme(self, force: bool = True):
|
|
156
183
|
"""
|
|
@@ -158,13 +185,11 @@ class Theme:
|
|
|
158
185
|
|
|
159
186
|
:param force: force theme change (manual trigger)
|
|
160
187
|
"""
|
|
161
|
-
|
|
162
|
-
self.toggle(current, force=force)
|
|
188
|
+
self.toggle(self.window.core.config.get('theme'), force=force)
|
|
163
189
|
|
|
164
190
|
def update_syntax(self):
|
|
165
191
|
"""Update syntax menu"""
|
|
166
|
-
|
|
167
|
-
self.toggle_syntax(current, update_menu=True)
|
|
192
|
+
self.toggle_syntax(self.window.core.config.get('render.code_syntax'), update_menu=True)
|
|
168
193
|
|
|
169
194
|
def reload(self, force: bool = True):
|
|
170
195
|
"""
|
|
@@ -254,8 +279,7 @@ class Theme:
|
|
|
254
279
|
|
|
255
280
|
:param prev_theme: previous theme name
|
|
256
281
|
"""
|
|
257
|
-
|
|
258
|
-
if not prev_theme or prev_theme != current_theme:
|
|
282
|
+
if not prev_theme or prev_theme != self.window.core.config.get('theme'):
|
|
259
283
|
self.setup()
|
|
260
284
|
self.update_style()
|
|
261
285
|
self.update_syntax()
|
|
@@ -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:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Dict, List
|
|
@@ -81,7 +81,7 @@ class Tools:
|
|
|
81
81
|
caller = parent
|
|
82
82
|
action = QAction(QIcon(icon), title, parent)
|
|
83
83
|
action.triggered.connect(
|
|
84
|
-
lambda idx=idx, column_idx=column_idx, id=id, caller=caller: caller.add_tab(idx, column_idx, Tab.TAB_TOOL, id)
|
|
84
|
+
lambda checked=False, idx=idx, column_idx=column_idx, id=id, caller=caller: caller.add_tab(idx, column_idx, Tab.TAB_TOOL, id)
|
|
85
85
|
)
|
|
86
86
|
submenu.addAction(action)
|
|
87
87
|
return submenu
|
pygpt_net/controller/ui/tabs.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.08.
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Any, Optional, Tuple
|
|
@@ -134,8 +134,7 @@ class Tabs:
|
|
|
134
134
|
def reload(self):
|
|
135
135
|
"""Reload tabs"""
|
|
136
136
|
self.window.core.tabs.reload()
|
|
137
|
-
|
|
138
|
-
self.window.dispatch(event)
|
|
137
|
+
self.window.dispatch(RenderEvent(RenderEvent.PREPARE))
|
|
139
138
|
self.debug()
|
|
140
139
|
|
|
141
140
|
def reload_after(self):
|
pygpt_net/controller/ui/ui.py
CHANGED
|
@@ -6,20 +6,20 @@
|
|
|
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.15
|
|
9
|
+
# Updated Date: 2025.08.23 15:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Optional
|
|
13
13
|
|
|
14
14
|
from PySide6.QtGui import QColor
|
|
15
15
|
|
|
16
|
+
from pygpt_net.core.events import BaseEvent, Event
|
|
16
17
|
from pygpt_net.utils import trans
|
|
17
18
|
|
|
18
19
|
from .mode import Mode
|
|
19
20
|
from .tabs import Tabs
|
|
20
21
|
from .vision import Vision
|
|
21
22
|
|
|
22
|
-
|
|
23
23
|
class UI:
|
|
24
24
|
def __init__(self, window=None):
|
|
25
25
|
"""
|
|
@@ -65,6 +65,20 @@ class UI:
|
|
|
65
65
|
self.vision.update()
|
|
66
66
|
self.window.controller.agent.legacy.update()
|
|
67
67
|
|
|
68
|
+
def handle(self, event: BaseEvent):
|
|
69
|
+
"""
|
|
70
|
+
Handle events
|
|
71
|
+
|
|
72
|
+
:param event: BaseEvent: Event to handle
|
|
73
|
+
"""
|
|
74
|
+
name = event.name
|
|
75
|
+
|
|
76
|
+
# on input begin
|
|
77
|
+
if name == Event.INPUT_BEGIN:
|
|
78
|
+
self.tabs.switch_to_first_chat() # switch to first active chat tab
|
|
79
|
+
elif name == Event.CTX_END:
|
|
80
|
+
self.update_tokens() # update UI
|
|
81
|
+
|
|
68
82
|
def get_colors(self) -> dict:
|
|
69
83
|
"""
|
|
70
84
|
Get color labels
|
|
@@ -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.
|
|
9
|
+
# Updated Date: 2025.08.24 02:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import List
|
|
@@ -188,8 +188,8 @@ class Evaluation:
|
|
|
188
188
|
i = 0
|
|
189
189
|
for ctx in history:
|
|
190
190
|
# if next input (but not last) then clear outputs - use only output after last user input
|
|
191
|
-
if self.is_input(ctx) and i < len(history) - 1:
|
|
192
|
-
outputs.clear()
|
|
191
|
+
# if self.is_input(ctx) and i < len(history) - 1:
|
|
192
|
+
# outputs.clear()
|
|
193
193
|
|
|
194
194
|
if self.is_output(ctx):
|
|
195
195
|
if ctx.output:
|
|
@@ -6,11 +6,13 @@
|
|
|
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.24 03:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
|
+
import os
|
|
12
|
+
from typing import List, Dict, Any
|
|
11
13
|
|
|
12
|
-
from
|
|
13
|
-
|
|
14
|
+
from pygpt_net.core.types import MODE_CHAT
|
|
15
|
+
from pygpt_net.item.model import ModelItem
|
|
14
16
|
from pygpt_net.provider.agents.base import BaseAgent
|
|
15
17
|
|
|
16
18
|
|
|
@@ -94,3 +96,23 @@ class Provider:
|
|
|
94
96
|
# sort by name
|
|
95
97
|
choices.sort(key=lambda x: list(x.values())[0].lower())
|
|
96
98
|
return choices
|
|
99
|
+
|
|
100
|
+
def get_openai_model(self, model: ModelItem) -> Any:
|
|
101
|
+
"""
|
|
102
|
+
Get OpenAI model by model id
|
|
103
|
+
|
|
104
|
+
:param model: ModelItem
|
|
105
|
+
:return: OpenAI model provider
|
|
106
|
+
"""
|
|
107
|
+
from openai import AsyncOpenAI
|
|
108
|
+
from agents import (
|
|
109
|
+
OpenAIChatCompletionsModel,
|
|
110
|
+
)
|
|
111
|
+
if model.provider == "openai":
|
|
112
|
+
return model.id
|
|
113
|
+
else:
|
|
114
|
+
args = self.window.core.models.prepare_client_args(MODE_CHAT, model)
|
|
115
|
+
return OpenAIChatCompletionsModel(
|
|
116
|
+
model=model.id,
|
|
117
|
+
openai_client=AsyncOpenAI(**args),
|
|
118
|
+
)
|
pygpt_net/core/agents/runner.py
CHANGED
|
@@ -105,6 +105,7 @@ class Runner:
|
|
|
105
105
|
# vector store idx from preset
|
|
106
106
|
if preset:
|
|
107
107
|
vector_store_idx = preset.idx
|
|
108
|
+
extra["agent_idx"] = vector_store_idx
|
|
108
109
|
|
|
109
110
|
# tools
|
|
110
111
|
agent_tools = self.window.core.agents.tools
|
|
@@ -126,7 +127,9 @@ class Runner:
|
|
|
126
127
|
|
|
127
128
|
# --- ADDITIONAL CONTEXT ---
|
|
128
129
|
# append additional context from RAG if available
|
|
129
|
-
if vector_store_idx
|
|
130
|
+
if (vector_store_idx
|
|
131
|
+
and vector_store_idx != "_"
|
|
132
|
+
and self.window.core.config.get("agent.idx.auto_retrieve", True)):
|
|
130
133
|
ad_context = self.window.core.idx.chat.query_retrieval(
|
|
131
134
|
query=prompt,
|
|
132
135
|
idx=vector_store_idx,
|
|
@@ -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.
|
|
9
|
+
# Updated Date: 2025.08.24 02:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import re
|
|
@@ -87,13 +87,14 @@ class LlamaWorkflow(BaseRunner):
|
|
|
87
87
|
self.set_idle(signals)
|
|
88
88
|
return False
|
|
89
89
|
|
|
90
|
+
use_current = False
|
|
90
91
|
if ctx.partial:
|
|
92
|
+
use_current = True # use current item as response if partial item (do not create new one)
|
|
91
93
|
ctx.partial = False # reset partial flag
|
|
92
94
|
|
|
93
|
-
response_ctx = self.make_response(ctx)
|
|
95
|
+
response_ctx = self.make_response(ctx, use_current=use_current)
|
|
94
96
|
self.end_stream(response_ctx, signals)
|
|
95
97
|
self.send_response(response_ctx, signals, KernelEvent.APPEND_DATA) # send response
|
|
96
|
-
|
|
97
98
|
self.set_idle(signals)
|
|
98
99
|
return True
|
|
99
100
|
|
|
@@ -152,19 +153,24 @@ class LlamaWorkflow(BaseRunner):
|
|
|
152
153
|
ctx.output = ctx.agent_final_response # set output to current context
|
|
153
154
|
else:
|
|
154
155
|
ctx.output = ctx.live_output
|
|
155
|
-
|
|
156
156
|
return ctx
|
|
157
157
|
|
|
158
158
|
def make_response(
|
|
159
159
|
self,
|
|
160
|
-
ctx: CtxItem
|
|
160
|
+
ctx: CtxItem,
|
|
161
|
+
use_current: bool = False
|
|
161
162
|
) -> CtxItem:
|
|
162
163
|
"""
|
|
163
164
|
Create a response context item with the given input and output.
|
|
164
165
|
|
|
165
166
|
:param ctx: CtxItem - the context item to use as a base
|
|
167
|
+
:param use_current: If True, use the current context item instead of creating a new one
|
|
166
168
|
"""
|
|
167
|
-
|
|
169
|
+
if use_current:
|
|
170
|
+
response_ctx = ctx # use current context item
|
|
171
|
+
else:
|
|
172
|
+
response_ctx = self.add_ctx(ctx, with_tool_outputs=True)
|
|
173
|
+
|
|
168
174
|
response_ctx.set_input("")
|
|
169
175
|
|
|
170
176
|
prev_output = ctx.live_output
|
|
@@ -176,6 +182,9 @@ class LlamaWorkflow(BaseRunner):
|
|
|
176
182
|
response_ctx.extra["agent_output"] = True # mark as output response
|
|
177
183
|
response_ctx.extra["agent_finish"] = True # mark as finished
|
|
178
184
|
|
|
185
|
+
if "agent_input" in response_ctx.extra:
|
|
186
|
+
del response_ctx.extra["agent_input"] # remove agent input from extra
|
|
187
|
+
|
|
179
188
|
if ctx.agent_final_response: # only if not empty
|
|
180
189
|
response_ctx.extra["output"] = ctx.agent_final_response
|
|
181
190
|
|
|
@@ -194,9 +203,12 @@ class LlamaWorkflow(BaseRunner):
|
|
|
194
203
|
:param output: Output string
|
|
195
204
|
:return: Filtered output string
|
|
196
205
|
"""
|
|
206
|
+
if output is None:
|
|
207
|
+
return ""
|
|
208
|
+
|
|
197
209
|
# Remove <execute>...</execute> tags
|
|
198
210
|
filtered_output = re.sub(r'<execute>.*?</execute>', '', output, flags=re.DOTALL)
|
|
199
|
-
return filtered_output
|
|
211
|
+
return filtered_output.strip()
|
|
200
212
|
|
|
201
213
|
async def run_agent(
|
|
202
214
|
self,
|
|
@@ -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.
|
|
9
|
+
# Updated Date: 2025.08.24 02:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Optional, List
|
|
@@ -136,6 +136,7 @@ class Loop(BaseRunner):
|
|
|
136
136
|
self.set_status(signals, msg)
|
|
137
137
|
if score < 0:
|
|
138
138
|
self.send_response(ctx, signals, KernelEvent.APPEND_END)
|
|
139
|
+
self.set_idle(signals)
|
|
139
140
|
return True
|
|
140
141
|
good_score = self.window.core.config.get("agent.llama.loop.score", 75)
|
|
141
142
|
if score >= good_score != 0:
|
|
@@ -145,6 +146,7 @@ class Loop(BaseRunner):
|
|
|
145
146
|
score=str(score)
|
|
146
147
|
)
|
|
147
148
|
self.send_response(ctx, signals, KernelEvent.APPEND_END, msg=msg)
|
|
149
|
+
self.set_idle(signals)
|
|
148
150
|
return True
|
|
149
151
|
|
|
150
152
|
# print("Instruction: " + instruction, "Score: " + str(score))
|
|
@@ -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.
|
|
9
|
+
# Updated Date: 2025.08.24 03:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Dict, Any, List
|
|
@@ -59,6 +59,9 @@ class OpenAIWorkflow(BaseRunner):
|
|
|
59
59
|
if self.is_stopped():
|
|
60
60
|
return True # abort if stopped
|
|
61
61
|
|
|
62
|
+
if "llm" in agent_kwargs:
|
|
63
|
+
agent_kwargs["llm"] = None # clear llm if provided, as it is not used in OpenAI workflow
|
|
64
|
+
|
|
62
65
|
self.set_busy(signals)
|
|
63
66
|
|
|
64
67
|
# append input to messages
|
|
@@ -69,7 +72,7 @@ class OpenAIWorkflow(BaseRunner):
|
|
|
69
72
|
self.window.core.gpt.vision.append_images(ctx) # append images to ctx if provided
|
|
70
73
|
history = history + msg
|
|
71
74
|
|
|
72
|
-
# callbacks
|
|
75
|
+
# ------------ callbacks ----------------
|
|
73
76
|
def on_step(
|
|
74
77
|
ctx: CtxItem,
|
|
75
78
|
begin: bool = False
|
|
@@ -136,6 +139,16 @@ class OpenAIWorkflow(BaseRunner):
|
|
|
136
139
|
self.send_stream(ctx, signals, False)
|
|
137
140
|
self.end_stream(ctx, signals)
|
|
138
141
|
|
|
142
|
+
# fix: prevent race condition with next context if feedback after response
|
|
143
|
+
if finish and input == output:
|
|
144
|
+
ctx.extra["agent_finish"] = True # mark as finished and ready for evaluation
|
|
145
|
+
ctx.extra["agent_finish_evaluate"] = True # mark as feedback response (ignored in loop evaluation)
|
|
146
|
+
if stream:
|
|
147
|
+
self.send_stream(ctx, signals, False)
|
|
148
|
+
self.end_stream(ctx, signals)
|
|
149
|
+
self.send_response(ctx, signals, KernelEvent.APPEND_DATA)
|
|
150
|
+
return ctx
|
|
151
|
+
|
|
139
152
|
# create and return next context item
|
|
140
153
|
next_ctx = self.add_next_ctx(ctx)
|
|
141
154
|
next_ctx.set_input(input)
|
|
@@ -158,7 +171,8 @@ class OpenAIWorkflow(BaseRunner):
|
|
|
158
171
|
self.set_idle(signals)
|
|
159
172
|
self.set_error(error)
|
|
160
173
|
|
|
161
|
-
# callbacks
|
|
174
|
+
# ------------ / callbacks ----------------
|
|
175
|
+
|
|
162
176
|
bridge = ConnectionContext(
|
|
163
177
|
stopped=self.is_stopped,
|
|
164
178
|
on_step=on_step,
|
pygpt_net/core/agents/tools.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.08.
|
|
9
|
+
# Updated Date: 2025.08.24 02:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import json
|
|
@@ -564,6 +564,9 @@ class CodeExecutor:
|
|
|
564
564
|
:param code: Python code to execute
|
|
565
565
|
:return: Output from the code execution
|
|
566
566
|
"""
|
|
567
|
+
if not self.window.core.command.is_cmd():
|
|
568
|
+
return "Tool execution is not enabled. Abort execution and ask user for tool enable."
|
|
569
|
+
|
|
567
570
|
self.window.core.agents.tools.last_tool_output = None
|
|
568
571
|
if code == "/restart":
|
|
569
572
|
commands = [
|