pygpt-net 2.6.21__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 +4 -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/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/audio/audio.py +2 -2
- pygpt_net/controller/ctx/ctx.py +2 -1
- pygpt_net/controller/idx/indexer.py +85 -76
- pygpt_net/controller/lang/lang.py +52 -34
- pygpt_net/controller/model/importer.py +2 -2
- pygpt_net/controller/notepad/notepad.py +86 -84
- pygpt_net/controller/plugins/settings.py +3 -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/core/ctx/container.py +13 -12
- pygpt_net/core/ctx/output.py +7 -4
- pygpt_net/core/debug/console/console.py +2 -2
- pygpt_net/core/filesystem/actions.py +1 -2
- 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/settings/settings.py +43 -13
- pygpt_net/core/tabs/tabs.py +20 -13
- pygpt_net/data/config/config.json +4 -4
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/locale/locale.de.ini +4 -1
- pygpt_net/data/locale/locale.en.ini +4 -1
- 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/plugin/twitter/plugin.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.21.dist-info → pygpt_net-2.6.22.dist-info}/METADATA +15 -151
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/RECORD +144 -144
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.21.dist-info → pygpt_net-2.6.22.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.21.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/core/ctx/container.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 List
|
|
@@ -15,9 +15,9 @@ from PySide6.QtWidgets import QVBoxLayout, QWidget
|
|
|
15
15
|
|
|
16
16
|
from pygpt_net.core.tabs.tab import Tab
|
|
17
17
|
from pygpt_net.ui.widget.textarea.output import ChatOutput
|
|
18
|
+
from pygpt_net.item.ctx import CtxItem
|
|
18
19
|
|
|
19
20
|
from .bag import Bag
|
|
20
|
-
from ...item.ctx import CtxItem
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class Container:
|
|
@@ -28,8 +28,7 @@ class Container:
|
|
|
28
28
|
:param window: Window
|
|
29
29
|
"""
|
|
30
30
|
self.window = window
|
|
31
|
-
self.bags = {}
|
|
32
|
-
self.bags[0] = Bag(window) # always create initial bag
|
|
31
|
+
self.bags = {0: Bag(window)}
|
|
33
32
|
|
|
34
33
|
def get(self, tab: Tab) -> QWidget:
|
|
35
34
|
"""
|
|
@@ -92,14 +91,16 @@ class Container:
|
|
|
92
91
|
|
|
93
92
|
:param tab: Tab
|
|
94
93
|
"""
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
94
|
+
nodes = self.window.ui.nodes
|
|
95
|
+
|
|
96
|
+
if tab.pid in nodes['output_plain']:
|
|
97
|
+
nodes['output_plain'][tab.pid].on_delete() # clean up
|
|
98
|
+
nodes['output_plain'][tab.pid] = None
|
|
99
|
+
del nodes['output_plain'][tab.pid]
|
|
100
|
+
if tab.pid in nodes['output']:
|
|
101
|
+
nodes['output'][tab.pid].on_delete() # clean up
|
|
102
|
+
nodes['output'][tab.pid] = None
|
|
103
|
+
del nodes['output'][tab.pid]
|
|
103
104
|
|
|
104
105
|
self.window.controller.chat.render.remove_pid(tab.pid) # remove pid data from renderer registry
|
|
105
106
|
self.window.core.ctx.output.remove_pid(tab.pid) # remove pid from ctx output mapping
|
pygpt_net/core/ctx/output.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:
|
|
9
|
+
# Updated Date: 2025.08.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Optional, List, Dict
|
|
@@ -87,6 +87,9 @@ class Output:
|
|
|
87
87
|
def is_mapped(self, meta: CtxMeta) -> bool:
|
|
88
88
|
"""
|
|
89
89
|
Check if meta is mapped anywhere
|
|
90
|
+
|
|
91
|
+
:param meta: Meta
|
|
92
|
+
:return: True if mapped, False otherwise
|
|
90
93
|
"""
|
|
91
94
|
self.init()
|
|
92
95
|
|
|
@@ -182,6 +185,8 @@ class Output:
|
|
|
182
185
|
def is_empty(self) -> bool:
|
|
183
186
|
"""
|
|
184
187
|
Check if mapping is empty for the active PID across columns
|
|
188
|
+
|
|
189
|
+
:return: True if empty, False otherwise
|
|
185
190
|
"""
|
|
186
191
|
self.init()
|
|
187
192
|
|
|
@@ -211,9 +216,7 @@ class Output:
|
|
|
211
216
|
return self.store(meta)
|
|
212
217
|
|
|
213
218
|
def clear(self):
|
|
214
|
-
"""
|
|
215
|
-
Clear mapping
|
|
216
|
-
"""
|
|
219
|
+
"""Clear mapping"""
|
|
217
220
|
self.mapping.clear()
|
|
218
221
|
self.last_pids.clear()
|
|
219
222
|
self.last_pid = 0
|
|
@@ -6,10 +6,10 @@
|
|
|
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
|
-
from
|
|
12
|
+
from PySide6.QtWidgets import QApplication
|
|
13
13
|
|
|
14
14
|
from pygpt_net.utils import mem_clean
|
|
15
15
|
|
|
@@ -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
|
import os
|
|
@@ -16,7 +16,6 @@ from PySide6.QtGui import QAction, QIcon
|
|
|
16
16
|
from PySide6.QtWidgets import QWidget
|
|
17
17
|
|
|
18
18
|
from pygpt_net.utils import trans
|
|
19
|
-
import pygpt_net.icons_rc
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
class Actions:
|
|
@@ -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.24 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
|
|
@@ -27,10 +27,7 @@ class Helpers:
|
|
|
27
27
|
:param text: text to format
|
|
28
28
|
:return: formatted text
|
|
29
29
|
"""
|
|
30
|
-
|
|
31
|
-
#text = text.replace("#~###~", "~###~") # fix for #~###~ in text (previous versions)
|
|
32
|
-
#text = text.replace("# ~###~", "~###~") # fix for # ~###~ in text (previous versions)
|
|
33
|
-
return text
|
|
30
|
+
return text.strip()
|
|
34
31
|
|
|
35
32
|
def post_format_text(self, text: str) -> str:
|
|
36
33
|
"""
|
|
@@ -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 datetime import datetime
|
|
@@ -178,11 +178,9 @@ class Renderer(BaseRenderer):
|
|
|
178
178
|
if clear:
|
|
179
179
|
self.clear_output(meta)
|
|
180
180
|
|
|
181
|
-
i
|
|
182
|
-
for item in items:
|
|
181
|
+
for i, item in enumerate(items):
|
|
183
182
|
item.idx = i
|
|
184
183
|
self.append_context_item(meta, item)
|
|
185
|
-
i += 1
|
|
186
184
|
|
|
187
185
|
def append_input(
|
|
188
186
|
self,
|
|
@@ -251,20 +249,23 @@ class Renderer(BaseRenderer):
|
|
|
251
249
|
:param item: context item
|
|
252
250
|
:param footer: True if it is a footer
|
|
253
251
|
"""
|
|
254
|
-
appended =
|
|
252
|
+
appended = set()
|
|
255
253
|
pid = self.get_or_create_pid(meta)
|
|
256
254
|
|
|
257
255
|
# images
|
|
258
256
|
c = len(item.images)
|
|
259
257
|
if c > 0:
|
|
260
258
|
n = 1
|
|
259
|
+
pd = self.pids[pid]
|
|
260
|
+
already = set(pd.images_appended)
|
|
261
261
|
for image in item.images:
|
|
262
|
-
if image in appended or image in
|
|
262
|
+
if image in appended or image in already:
|
|
263
263
|
continue
|
|
264
264
|
try:
|
|
265
|
-
appended.
|
|
265
|
+
appended.add(image)
|
|
266
266
|
self.append_raw(meta, item, self.body.get_image_html(image, n, c))
|
|
267
|
-
|
|
267
|
+
pd.images_appended.append(image)
|
|
268
|
+
already.add(image)
|
|
268
269
|
n += 1
|
|
269
270
|
except Exception as e:
|
|
270
271
|
pass
|
|
@@ -277,7 +278,7 @@ class Renderer(BaseRenderer):
|
|
|
277
278
|
if file in appended:
|
|
278
279
|
continue
|
|
279
280
|
try:
|
|
280
|
-
appended.
|
|
281
|
+
appended.add(file)
|
|
281
282
|
self.append_raw(meta, item, self.body.get_file_html(file, n, c))
|
|
282
283
|
n += 1
|
|
283
284
|
except Exception as e:
|
|
@@ -288,13 +289,16 @@ class Renderer(BaseRenderer):
|
|
|
288
289
|
if c > 0:
|
|
289
290
|
urls_str = []
|
|
290
291
|
n = 1
|
|
292
|
+
pd = self.pids[pid]
|
|
293
|
+
already = set(pd.urls_appended)
|
|
291
294
|
for url in item.urls:
|
|
292
|
-
if url in appended or url in
|
|
295
|
+
if url in appended or url in already:
|
|
293
296
|
continue
|
|
294
297
|
try:
|
|
295
|
-
appended.
|
|
298
|
+
appended.add(url)
|
|
296
299
|
urls_str.append(self.body.get_url_html(url, n, c))
|
|
297
|
-
|
|
300
|
+
pd.urls_appended.append(url)
|
|
301
|
+
already.add(url)
|
|
298
302
|
n += 1
|
|
299
303
|
except Exception as e:
|
|
300
304
|
pass
|
|
@@ -337,8 +341,9 @@ class Renderer(BaseRenderer):
|
|
|
337
341
|
raw_chunk = str(text_chunk)
|
|
338
342
|
|
|
339
343
|
if begin:
|
|
340
|
-
self.pids[pid]
|
|
341
|
-
|
|
344
|
+
pd = self.pids[pid]
|
|
345
|
+
pd.buffer = ""
|
|
346
|
+
pd.is_cmd = False
|
|
342
347
|
|
|
343
348
|
if self.is_timestamp_enabled() and item.output_timestamp is not None:
|
|
344
349
|
name = ""
|
|
@@ -386,13 +391,12 @@ class Renderer(BaseRenderer):
|
|
|
386
391
|
:param text: text to append
|
|
387
392
|
"""
|
|
388
393
|
node = self.get_output_node(meta)
|
|
389
|
-
|
|
390
|
-
if prev_text != "":
|
|
391
|
-
prev_text += "\n\n"
|
|
392
|
-
new_text = f"{prev_text}{text.strip()}"
|
|
393
|
-
node.setPlainText(new_text)
|
|
394
|
-
cur = node.textCursor() # Move cursor to end of text
|
|
394
|
+
cur = node.textCursor()
|
|
395
395
|
cur.movePosition(QTextCursor.End)
|
|
396
|
+
if not node.document().isEmpty():
|
|
397
|
+
cur.insertText("\n\n")
|
|
398
|
+
cur.insertText(text.strip())
|
|
399
|
+
node.setTextCursor(cur)
|
|
396
400
|
|
|
397
401
|
def append_chunk_start(self, meta: CtxMeta, ctx: CtxItem):
|
|
398
402
|
"""
|
|
@@ -437,14 +441,9 @@ class Renderer(BaseRenderer):
|
|
|
437
441
|
:param end: end of the line character
|
|
438
442
|
"""
|
|
439
443
|
node = self.get_output_node(meta)
|
|
440
|
-
cur = node.textCursor()
|
|
444
|
+
cur = node.textCursor()
|
|
441
445
|
cur.movePosition(QTextCursor.End)
|
|
442
|
-
|
|
443
|
-
while s:
|
|
444
|
-
head, sep, s = s.partition("\n") # Split line at LF
|
|
445
|
-
cur.insertText(head)
|
|
446
|
-
if sep:
|
|
447
|
-
cur.insertText("\n")
|
|
446
|
+
cur.insertText(f"{str(text)}{end}")
|
|
448
447
|
node.setTextCursor(cur)
|
|
449
448
|
|
|
450
449
|
def append_timestamp(
|
|
@@ -549,9 +548,6 @@ class Renderer(BaseRenderer):
|
|
|
549
548
|
for node in self.get_all_nodes():
|
|
550
549
|
try:
|
|
551
550
|
node.clear()
|
|
552
|
-
node.document().setMarkdown("")
|
|
553
|
-
node.document().setHtml("")
|
|
554
|
-
node.setPlainText("")
|
|
555
551
|
except Exception as e:
|
|
556
552
|
pass
|
|
557
553
|
|