pygpt-net 2.6.34__py3-none-any.whl → 2.6.35__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 +7 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/chat/common.py +8 -2
- pygpt_net/controller/chat/handler/stream_worker.py +55 -43
- pygpt_net/controller/painter/common.py +13 -1
- pygpt_net/controller/painter/painter.py +11 -2
- pygpt_net/core/bridge/bridge.py +1 -5
- pygpt_net/core/bridge/context.py +81 -36
- pygpt_net/core/bridge/worker.py +3 -1
- pygpt_net/core/ctx/bag.py +4 -0
- pygpt_net/core/events/app.py +10 -17
- pygpt_net/core/events/base.py +17 -25
- pygpt_net/core/events/control.py +9 -17
- pygpt_net/core/events/event.py +9 -62
- pygpt_net/core/events/kernel.py +8 -17
- pygpt_net/core/events/realtime.py +8 -17
- pygpt_net/core/events/render.py +9 -17
- pygpt_net/core/render/web/body.py +394 -36
- pygpt_net/core/render/web/pid.py +39 -24
- pygpt_net/core/render/web/renderer.py +146 -40
- pygpt_net/data/config/config.json +4 -3
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/css/web-blocks.css +3 -2
- pygpt_net/data/css/web-chatgpt.css +3 -1
- pygpt_net/data/css/web-chatgpt_wide.css +3 -1
- pygpt_net/data/locale/locale.de.ini +1 -0
- pygpt_net/data/locale/locale.en.ini +3 -2
- pygpt_net/data/locale/locale.es.ini +1 -0
- pygpt_net/data/locale/locale.fr.ini +1 -0
- pygpt_net/data/locale/locale.it.ini +1 -0
- pygpt_net/data/locale/locale.pl.ini +2 -1
- pygpt_net/data/locale/locale.uk.ini +1 -0
- pygpt_net/data/locale/locale.zh.ini +1 -0
- pygpt_net/provider/api/google/__init__.py +14 -5
- pygpt_net/provider/api/openai/__init__.py +13 -10
- pygpt_net/provider/core/config/patch.py +9 -0
- pygpt_net/ui/layout/chat/painter.py +63 -4
- pygpt_net/ui/widget/draw/painter.py +702 -106
- pygpt_net/ui/widget/textarea/web.py +2 -0
- {pygpt_net-2.6.34.dist-info → pygpt_net-2.6.35.dist-info}/METADATA +9 -2
- {pygpt_net-2.6.34.dist-info → pygpt_net-2.6.35.dist-info}/RECORD +44 -44
- {pygpt_net-2.6.34.dist-info → pygpt_net-2.6.35.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.34.dist-info → pygpt_net-2.6.35.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.34.dist-info → pygpt_net-2.6.35.dist-info}/entry_points.txt +0 -0
|
@@ -81,16 +81,7 @@ class ApiOpenAI:
|
|
|
81
81
|
"""
|
|
82
82
|
# update client args by mode and model
|
|
83
83
|
args = self.window.core.models.prepare_client_args(mode, model)
|
|
84
|
-
|
|
85
|
-
if self.client is not None:
|
|
86
|
-
try:
|
|
87
|
-
self.client.close() # close previous client if exists
|
|
88
|
-
except Exception as e:
|
|
89
|
-
self.window.core.debug.log(e)
|
|
90
|
-
print("Error closing previous GPT client:", e)
|
|
91
|
-
self.client = OpenAI(**args)
|
|
92
|
-
self.last_client_args = args
|
|
93
|
-
return self.client
|
|
84
|
+
return OpenAI(**args)
|
|
94
85
|
|
|
95
86
|
def call(
|
|
96
87
|
self,
|
|
@@ -342,3 +333,15 @@ class ApiOpenAI:
|
|
|
342
333
|
except Exception as e:
|
|
343
334
|
self.window.core.debug.log(e)
|
|
344
335
|
print("Error closing GPT client:", e)
|
|
336
|
+
|
|
337
|
+
def safe_close(self):
|
|
338
|
+
"""Close client"""
|
|
339
|
+
if self.locked:
|
|
340
|
+
return
|
|
341
|
+
if self.client is not None:
|
|
342
|
+
try:
|
|
343
|
+
self.client.close()
|
|
344
|
+
self.client = None
|
|
345
|
+
except Exception as e:
|
|
346
|
+
self.window.core.debug.log(e)
|
|
347
|
+
print("Error closing client:", e)
|
|
@@ -2429,6 +2429,15 @@ class Patch:
|
|
|
2429
2429
|
patch_css('web-blocks.css', True)
|
|
2430
2430
|
updated = True
|
|
2431
2431
|
|
|
2432
|
+
# < 2.6.35
|
|
2433
|
+
if old < parse_version("2.6.35"):
|
|
2434
|
+
print("Migrating config from < 2.6.35...")
|
|
2435
|
+
# remove will-change
|
|
2436
|
+
patch_css('web-chatgpt.css', True)
|
|
2437
|
+
patch_css('web-chatgpt_wide.css', True)
|
|
2438
|
+
patch_css('web-blocks.css', True)
|
|
2439
|
+
updated = True
|
|
2440
|
+
|
|
2432
2441
|
# update file
|
|
2433
2442
|
migrated = False
|
|
2434
2443
|
if updated:
|
|
@@ -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.09.02 15:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtGui import QPixmap, QIcon
|
|
@@ -15,7 +15,6 @@ from PySide6.QtCore import QSize
|
|
|
15
15
|
|
|
16
16
|
from pygpt_net.ui.widget.draw.painter import PainterWidget
|
|
17
17
|
from pygpt_net.ui.widget.element.labels import HelpLabel
|
|
18
|
-
from pygpt_net.ui.widget.tabs.body import TabBody
|
|
19
18
|
from pygpt_net.utils import trans
|
|
20
19
|
|
|
21
20
|
|
|
@@ -90,6 +89,63 @@ class Painter:
|
|
|
90
89
|
cb.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
|
91
90
|
nodes[key] = cb
|
|
92
91
|
|
|
92
|
+
# Zoom combo (view-only scale) placed to the right of canvas size
|
|
93
|
+
key = 'painter.select.zoom'
|
|
94
|
+
if nodes.get(key) is None:
|
|
95
|
+
cb = QComboBox()
|
|
96
|
+
cb.setMinimumContentsLength(8)
|
|
97
|
+
cb.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
|
98
|
+
|
|
99
|
+
# Preferred preset steps from widget; fallback to defaults
|
|
100
|
+
steps = []
|
|
101
|
+
if hasattr(ui.painter, 'get_zoom_steps_percent'):
|
|
102
|
+
try:
|
|
103
|
+
steps = ui.painter.get_zoom_steps_percent()
|
|
104
|
+
except Exception:
|
|
105
|
+
steps = []
|
|
106
|
+
if not steps:
|
|
107
|
+
steps = [10, 25, 50, 75, 100, 150, 200, 500, 1000]
|
|
108
|
+
|
|
109
|
+
cb.addItems([f"{p}%" for p in steps])
|
|
110
|
+
|
|
111
|
+
# User -> widget
|
|
112
|
+
cb.currentTextChanged.connect(ui.painter.on_zoom_combo_changed)
|
|
113
|
+
|
|
114
|
+
# Widget -> combo (also covers CTRL+wheel and programmatic changes)
|
|
115
|
+
def _sync_zoom_combo_from_widget(z):
|
|
116
|
+
"""Keep zoom combobox in sync with the widget's zoom."""
|
|
117
|
+
percent = int(round(float(z) * 100))
|
|
118
|
+
label = f"{percent}%"
|
|
119
|
+
cb.blockSignals(True)
|
|
120
|
+
idx = cb.findText(label)
|
|
121
|
+
if idx >= 0:
|
|
122
|
+
cb.setCurrentIndex(idx)
|
|
123
|
+
else:
|
|
124
|
+
# Insert missing value keeping ascending order
|
|
125
|
+
items = [cb.itemText(i) for i in range(cb.count())]
|
|
126
|
+
if label not in items:
|
|
127
|
+
items.append(label)
|
|
128
|
+
try:
|
|
129
|
+
items_sorted = sorted(
|
|
130
|
+
set(items),
|
|
131
|
+
key=lambda s: float(s.replace('%', '').strip())
|
|
132
|
+
)
|
|
133
|
+
except Exception:
|
|
134
|
+
items_sorted = items
|
|
135
|
+
cb.clear()
|
|
136
|
+
cb.addItems(items_sorted)
|
|
137
|
+
cb.setCurrentText(label)
|
|
138
|
+
cb.blockSignals(False)
|
|
139
|
+
|
|
140
|
+
# Keep reference to prevent GC of the inner function
|
|
141
|
+
cb._sync_zoom_combo_from_widget = _sync_zoom_combo_from_widget
|
|
142
|
+
if hasattr(ui.painter, 'zoomChanged'):
|
|
143
|
+
ui.painter.zoomChanged.connect(cb._sync_zoom_combo_from_widget)
|
|
144
|
+
|
|
145
|
+
# Initial label; actual value will be set by load_zoom below
|
|
146
|
+
cb.setCurrentText("100%")
|
|
147
|
+
nodes[key] = cb
|
|
148
|
+
|
|
93
149
|
self._initialized = True
|
|
94
150
|
|
|
95
151
|
def setup(self) -> QWidget:
|
|
@@ -118,6 +174,8 @@ class Painter:
|
|
|
118
174
|
top.addWidget(nodes['painter.select.brush.size'])
|
|
119
175
|
top.addWidget(nodes['painter.select.brush.color'])
|
|
120
176
|
top.addWidget(nodes['painter.select.canvas.size'])
|
|
177
|
+
# Zoom combo placed right after canvas size
|
|
178
|
+
top.addWidget(nodes['painter.select.zoom'])
|
|
121
179
|
top.addStretch(1)
|
|
122
180
|
|
|
123
181
|
if nodes.get('painter.btn.capture') is None:
|
|
@@ -141,11 +199,12 @@ class Painter:
|
|
|
141
199
|
if getattr(ui, 'painter_scroll', None) is None:
|
|
142
200
|
ui.painter_scroll = QScrollArea()
|
|
143
201
|
ui.painter_scroll.setWidget(ui.painter)
|
|
144
|
-
|
|
202
|
+
# Must be False to allow content widget to grow/shrink with zoom and show scrollbars
|
|
203
|
+
ui.painter_scroll.setWidgetResizable(False)
|
|
145
204
|
else:
|
|
146
205
|
if ui.painter_scroll.widget() is not ui.painter:
|
|
147
206
|
ui.painter_scroll.setWidget(ui.painter)
|
|
148
|
-
ui.painter_scroll.setWidgetResizable(
|
|
207
|
+
ui.painter_scroll.setWidgetResizable(False)
|
|
149
208
|
|
|
150
209
|
if nodes.get('tip.output.tab.draw') is None:
|
|
151
210
|
nodes['tip.output.tab.draw'] = HelpLabel(trans('tip.output.tab.draw'), self.window)
|