pygpt-net 2.7.0__py3-none-any.whl → 2.7.1__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 +8 -0
- pygpt_net/__init__.py +1 -1
- pygpt_net/controller/ctx/ctx.py +4 -1
- pygpt_net/controller/painter/common.py +43 -11
- pygpt_net/core/filesystem/filesystem.py +70 -0
- pygpt_net/core/filesystem/packer.py +161 -1
- pygpt_net/core/image/image.py +2 -2
- pygpt_net/core/video/video.py +2 -3
- pygpt_net/data/config/config.json +2 -2
- pygpt_net/data/config/models.json +2 -2
- pygpt_net/data/css/style.dark.css +12 -5
- pygpt_net/data/css/style.light.css +12 -4
- 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/provider/core/config/patch.py +8 -0
- pygpt_net/ui/dialog/preset.py +1 -0
- pygpt_net/ui/layout/toolbox/image.py +2 -1
- pygpt_net/ui/layout/toolbox/indexes.py +2 -0
- pygpt_net/ui/layout/toolbox/video.py +5 -1
- pygpt_net/ui/widget/draw/painter.py +238 -51
- pygpt_net/ui/widget/filesystem/explorer.py +82 -0
- pygpt_net/ui/widget/option/combo.py +177 -13
- {pygpt_net-2.7.0.dist-info → pygpt_net-2.7.1.dist-info}/METADATA +10 -2
- {pygpt_net-2.7.0.dist-info → pygpt_net-2.7.1.dist-info}/RECORD +33 -33
- {pygpt_net-2.7.0.dist-info → pygpt_net-2.7.1.dist-info}/LICENSE +0 -0
- {pygpt_net-2.7.0.dist-info → pygpt_net-2.7.1.dist-info}/WHEEL +0 -0
- {pygpt_net-2.7.0.dist-info → pygpt_net-2.7.1.dist-info}/entry_points.txt +0 -0
|
@@ -723,6 +723,8 @@ class FileExplorer(QWidget):
|
|
|
723
723
|
'paste': QIcon(":/icons/paste.svg"),
|
|
724
724
|
'read': QIcon(":/icons/view.svg"),
|
|
725
725
|
'db': QIcon(":/icons/db.svg"),
|
|
726
|
+
'pack': QIcon(":/icons/upload.svg"),
|
|
727
|
+
'unpack': QIcon(":/icons/download.svg"),
|
|
726
728
|
}
|
|
727
729
|
|
|
728
730
|
try:
|
|
@@ -996,6 +998,16 @@ class FileExplorer(QWidget):
|
|
|
996
998
|
actions['paste'].triggered.connect(lambda: self.action_paste_into(parent))
|
|
997
999
|
actions['paste'].setEnabled(self._can_paste())
|
|
998
1000
|
|
|
1001
|
+
# Pack / Unpack availability
|
|
1002
|
+
try:
|
|
1003
|
+
can_unpack_all = all(
|
|
1004
|
+
os.path.isfile(p) and self.window.core.filesystem.packer.can_unpack(p)
|
|
1005
|
+
for p in paths
|
|
1006
|
+
)
|
|
1007
|
+
except Exception:
|
|
1008
|
+
can_unpack_all = False
|
|
1009
|
+
|
|
1010
|
+
# Build menu
|
|
999
1011
|
menu = QMenu(self)
|
|
1000
1012
|
if preview_actions:
|
|
1001
1013
|
for action in preview_actions:
|
|
@@ -1076,6 +1088,23 @@ class FileExplorer(QWidget):
|
|
|
1076
1088
|
menu.addAction(actions['paste'])
|
|
1077
1089
|
menu.addSeparator()
|
|
1078
1090
|
|
|
1091
|
+
# Pack submenu (available for any selection)
|
|
1092
|
+
pack_menu = QMenu(trans("action.pack"), self)
|
|
1093
|
+
a_zip = QAction(self._icons['pack'], "ZIP (.zip)", self)
|
|
1094
|
+
a_zip.triggered.connect(lambda: self.action_pack(target_multi, 'zip'))
|
|
1095
|
+
a_tgz = QAction(self._icons['pack'], "Tar GZip (.tar.gz)", self)
|
|
1096
|
+
a_tgz.triggered.connect(lambda: self.action_pack(target_multi, 'tar.gz'))
|
|
1097
|
+
pack_menu.addAction(a_zip)
|
|
1098
|
+
pack_menu.addAction(a_tgz)
|
|
1099
|
+
menu.addMenu(pack_menu)
|
|
1100
|
+
|
|
1101
|
+
# Unpack (only when all selected are supported archives)
|
|
1102
|
+
if can_unpack_all:
|
|
1103
|
+
a_unpack = QAction(self._icons['unpack'], trans("action.unpack"), self)
|
|
1104
|
+
a_unpack.triggered.connect(lambda: self.action_unpack(target_multi))
|
|
1105
|
+
menu.addAction(a_unpack)
|
|
1106
|
+
|
|
1107
|
+
menu.addSeparator()
|
|
1079
1108
|
menu.addAction(actions['download'])
|
|
1080
1109
|
menu.addAction(actions['touch'])
|
|
1081
1110
|
menu.addAction(actions['mkdir'])
|
|
@@ -1180,6 +1209,59 @@ class FileExplorer(QWidget):
|
|
|
1180
1209
|
"""
|
|
1181
1210
|
self.window.controller.files.delete(path)
|
|
1182
1211
|
|
|
1212
|
+
def action_pack(self, path: Union[str, list], fmt: str):
|
|
1213
|
+
"""
|
|
1214
|
+
Pack selected items into an archive.
|
|
1215
|
+
|
|
1216
|
+
:param path: path or list of paths to include
|
|
1217
|
+
:param fmt: 'zip' or 'tar.gz'
|
|
1218
|
+
"""
|
|
1219
|
+
paths = path if isinstance(path, list) else [path]
|
|
1220
|
+
try:
|
|
1221
|
+
dst = self.window.core.filesystem.packer.pack_paths(paths, fmt)
|
|
1222
|
+
except Exception as e:
|
|
1223
|
+
try:
|
|
1224
|
+
self.window.core.debug.log(e)
|
|
1225
|
+
except Exception:
|
|
1226
|
+
pass
|
|
1227
|
+
dst = None
|
|
1228
|
+
|
|
1229
|
+
try:
|
|
1230
|
+
self.window.controller.files.update_explorer()
|
|
1231
|
+
except Exception:
|
|
1232
|
+
self.update_view()
|
|
1233
|
+
|
|
1234
|
+
if dst and os.path.exists(dst):
|
|
1235
|
+
self._reveal_paths([dst], select_first=True)
|
|
1236
|
+
|
|
1237
|
+
def action_unpack(self, path: Union[str, list]):
|
|
1238
|
+
"""
|
|
1239
|
+
Unpack selected archives to sibling directories named after archives.
|
|
1240
|
+
|
|
1241
|
+
:param path: path or list of paths to archives
|
|
1242
|
+
"""
|
|
1243
|
+
paths = path if isinstance(path, list) else [path]
|
|
1244
|
+
created = []
|
|
1245
|
+
for p in paths:
|
|
1246
|
+
try:
|
|
1247
|
+
if self.window.core.filesystem.packer.can_unpack(p):
|
|
1248
|
+
out_dir = self.window.core.filesystem.packer.unpack_to_sibling_dir(p)
|
|
1249
|
+
if out_dir:
|
|
1250
|
+
created.append(out_dir)
|
|
1251
|
+
except Exception as e:
|
|
1252
|
+
try:
|
|
1253
|
+
self.window.core.debug.log(e)
|
|
1254
|
+
except Exception:
|
|
1255
|
+
pass
|
|
1256
|
+
|
|
1257
|
+
try:
|
|
1258
|
+
self.window.controller.files.update_explorer()
|
|
1259
|
+
except Exception:
|
|
1260
|
+
self.update_view()
|
|
1261
|
+
|
|
1262
|
+
if created:
|
|
1263
|
+
self._reveal_paths(created, select_first=True)
|
|
1264
|
+
|
|
1183
1265
|
# ===== Copy / Cut / Paste API =====
|
|
1184
1266
|
|
|
1185
1267
|
def _selected_paths(self) -> list:
|
|
@@ -393,6 +393,15 @@ class SearchableCombo(SeparatorComboBox):
|
|
|
393
393
|
self._last_query_text: str = ""
|
|
394
394
|
self._suppress_search: bool = False
|
|
395
395
|
|
|
396
|
+
# Guard flags for mouse handling
|
|
397
|
+
self._swallow_release_once: bool = False # kept for compatibility; not used in the new flow
|
|
398
|
+
self._open_on_release: bool = False # open popup on mouse release (non-arrow path)
|
|
399
|
+
|
|
400
|
+
# Popup fitting helpers
|
|
401
|
+
self._fit_in_progress: bool = False
|
|
402
|
+
self._popup_parent_window = None
|
|
403
|
+
self._popup_right_margin_px: int = 4 # small safety margin from window right edge
|
|
404
|
+
|
|
396
405
|
self._install_persistent_editor()
|
|
397
406
|
self._init_popup_view_style_targets()
|
|
398
407
|
|
|
@@ -491,13 +500,18 @@ class SearchableCombo(SeparatorComboBox):
|
|
|
491
500
|
if self.search:
|
|
492
501
|
self._prepare_popup_header()
|
|
493
502
|
|
|
503
|
+
# Ensure geometry fits horizontally within window bounds
|
|
504
|
+
self._fit_popup_to_window()
|
|
494
505
|
QTimer.singleShot(0, self._apply_popup_max_rows)
|
|
506
|
+
QTimer.singleShot(0, self._fit_popup_to_window)
|
|
495
507
|
self._refresh_popup_view()
|
|
496
508
|
|
|
497
509
|
def hidePopup(self):
|
|
498
510
|
"""Close popup and restore normal display text; remove header/margins."""
|
|
499
511
|
super().hidePopup()
|
|
500
512
|
self._popup_open = False
|
|
513
|
+
self._swallow_release_once = False # ensure release guard is cleared when popup closes
|
|
514
|
+
self._open_on_release = False
|
|
501
515
|
|
|
502
516
|
if self._popup_header is not None:
|
|
503
517
|
try:
|
|
@@ -539,12 +553,22 @@ class SearchableCombo(SeparatorComboBox):
|
|
|
539
553
|
try:
|
|
540
554
|
container.setObjectName("ComboPopupWindow") # QWidget#ComboPopupWindow { ... }
|
|
541
555
|
container.setProperty("class", "combo-popup-window")
|
|
556
|
+
container.setAttribute(Qt.WA_NoMouseReplay, True) # prevent unwanted mouse replays on popup show
|
|
542
557
|
except Exception:
|
|
543
558
|
pass
|
|
544
559
|
|
|
545
560
|
self._popup_container = container
|
|
546
561
|
container.installEventFilter(self)
|
|
547
562
|
|
|
563
|
+
# Track parent window moves/resizes while popup is open
|
|
564
|
+
try:
|
|
565
|
+
top = self.window()
|
|
566
|
+
if top is not None:
|
|
567
|
+
top.installEventFilter(self)
|
|
568
|
+
self._popup_parent_window = top
|
|
569
|
+
except Exception:
|
|
570
|
+
self._popup_parent_window = None
|
|
571
|
+
|
|
548
572
|
if self._popup_header is None:
|
|
549
573
|
self._popup_header = QLineEdit(container)
|
|
550
574
|
self._popup_header.setObjectName("comboSearchHeader")
|
|
@@ -619,7 +643,14 @@ class SearchableCombo(SeparatorComboBox):
|
|
|
619
643
|
self._popup_container.removeEventFilter(self)
|
|
620
644
|
except Exception:
|
|
621
645
|
pass
|
|
646
|
+
# Unhook parent window filter if any
|
|
647
|
+
if self._popup_parent_window is not None:
|
|
648
|
+
try:
|
|
649
|
+
self._popup_parent_window.removeEventFilter(self)
|
|
650
|
+
except Exception:
|
|
651
|
+
pass
|
|
622
652
|
self._popup_container = None
|
|
653
|
+
self._popup_parent_window = None
|
|
623
654
|
|
|
624
655
|
# ----- Mouse handling on combo (display area) -----
|
|
625
656
|
|
|
@@ -637,25 +668,51 @@ class SearchableCombo(SeparatorComboBox):
|
|
|
637
668
|
|
|
638
669
|
def mousePressEvent(self, event):
|
|
639
670
|
"""
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
:param event: QMouseEvent
|
|
671
|
+
Use release-to-open on the non-arrow area to avoid immediate close when the popup opens upward.
|
|
672
|
+
Keep the arrow area with the default toggle behaviour from the base class.
|
|
643
673
|
"""
|
|
644
674
|
if event.button() == Qt.LeftButton and self.isEnabled():
|
|
645
675
|
arrow_rect = self._arrow_rect()
|
|
646
676
|
if arrow_rect.contains(event.pos()):
|
|
677
|
+
# Arrow path: keep default toggle semantics
|
|
678
|
+
self._open_on_release = False
|
|
679
|
+
self._swallow_release_once = False
|
|
647
680
|
return super().mousePressEvent(event)
|
|
648
|
-
|
|
649
|
-
|
|
681
|
+
|
|
682
|
+
# Non-arrow path
|
|
683
|
+
if self._popup_open:
|
|
684
|
+
# Toggle close if already open
|
|
685
|
+
self.hidePopup()
|
|
686
|
+
self._open_on_release = False
|
|
687
|
+
self._swallow_release_once = False
|
|
688
|
+
event.accept()
|
|
689
|
+
return
|
|
690
|
+
|
|
691
|
+
# Defer opening until mouse release to prevent instant close when popup is above
|
|
692
|
+
self._open_on_release = True
|
|
693
|
+
self._swallow_release_once = False
|
|
650
694
|
event.accept()
|
|
651
695
|
return
|
|
696
|
+
|
|
652
697
|
super().mousePressEvent(event)
|
|
653
698
|
|
|
699
|
+
def mouseReleaseEvent(self, event):
|
|
700
|
+
"""
|
|
701
|
+
Open the popup on release if the press started on the non-arrow area.
|
|
702
|
+
This avoids the popup being created mid-click (which can close immediately when opening upward).
|
|
703
|
+
"""
|
|
704
|
+
if event.button() == Qt.LeftButton and self._open_on_release:
|
|
705
|
+
self._open_on_release = False
|
|
706
|
+
if self.isEnabled() and not self._popup_open and self.rect().contains(event.pos()):
|
|
707
|
+
self.showPopup()
|
|
708
|
+
event.accept()
|
|
709
|
+
return
|
|
710
|
+
|
|
711
|
+
super().mouseReleaseEvent(event)
|
|
712
|
+
|
|
654
713
|
def keyPressEvent(self, event):
|
|
655
714
|
"""
|
|
656
715
|
Commit the highlighted item with Enter/Return while the popup is open.
|
|
657
|
-
|
|
658
|
-
:param event: QKeyEvent
|
|
659
716
|
"""
|
|
660
717
|
if self._popup_open:
|
|
661
718
|
if event.key() in (Qt.Key_Return, Qt.Key_Enter):
|
|
@@ -675,13 +732,19 @@ class SearchableCombo(SeparatorComboBox):
|
|
|
675
732
|
- Handle navigation/confirm keys in the header.
|
|
676
733
|
- Handle Enter on the popup list as well.
|
|
677
734
|
- Do not close popup on ESC.
|
|
678
|
-
|
|
679
|
-
:param obj: QObject
|
|
680
|
-
:param event: QEvent
|
|
735
|
+
- Keep popup horizontally inside the parent window while resizing/moving.
|
|
681
736
|
"""
|
|
682
737
|
if obj is self._popup_container and self._popup_container is not None:
|
|
683
738
|
if event.type() in (QEvent.Resize, QEvent.Show):
|
|
684
739
|
self._place_popup_header()
|
|
740
|
+
# Also ensure fitting after container geometry changes
|
|
741
|
+
self._fit_popup_to_window()
|
|
742
|
+
return False
|
|
743
|
+
|
|
744
|
+
# Track top-level parent window resize/move to keep popup clamped within it
|
|
745
|
+
if obj is self._popup_parent_window and self._popup_parent_window is not None:
|
|
746
|
+
if event.type() in (QEvent.Resize, QEvent.Move):
|
|
747
|
+
self._fit_popup_to_window()
|
|
685
748
|
return False
|
|
686
749
|
|
|
687
750
|
if obj is self._popup_header:
|
|
@@ -1119,6 +1182,99 @@ class SearchableCombo(SeparatorComboBox):
|
|
|
1119
1182
|
except Exception:
|
|
1120
1183
|
pass
|
|
1121
1184
|
|
|
1185
|
+
# ----- Horizontal fitting helpers (keep popup inside window bounds) -----
|
|
1186
|
+
|
|
1187
|
+
def _popup_allowed_rect(self) -> QRect:
|
|
1188
|
+
"""Return the allowed global rectangle for the popup (intersection of window frame and screen)."""
|
|
1189
|
+
try:
|
|
1190
|
+
win = self.window()
|
|
1191
|
+
if win is not None:
|
|
1192
|
+
allowed = win.frameGeometry()
|
|
1193
|
+
else:
|
|
1194
|
+
scr = self.screen()
|
|
1195
|
+
allowed = scr.availableGeometry() if scr is not None else None
|
|
1196
|
+
# Intersect with the window's screen available area to avoid going off-screen
|
|
1197
|
+
scr = (win.screen() if win is not None else self.screen())
|
|
1198
|
+
if allowed is not None and scr is not None:
|
|
1199
|
+
allowed = allowed.intersected(scr.availableGeometry())
|
|
1200
|
+
if allowed is None:
|
|
1201
|
+
scr = self.screen()
|
|
1202
|
+
allowed = scr.availableGeometry() if scr is not None else QRect(0, 0, 1920, 1080)
|
|
1203
|
+
except Exception:
|
|
1204
|
+
allowed = QRect(0, 0, 1920, 1080)
|
|
1205
|
+
# Small inward adjustment to avoid touching the edge
|
|
1206
|
+
try:
|
|
1207
|
+
margin = max(0, int(self._popup_right_margin_px))
|
|
1208
|
+
except Exception:
|
|
1209
|
+
margin = 4
|
|
1210
|
+
return allowed.adjusted(margin, 0, -margin, 0)
|
|
1211
|
+
|
|
1212
|
+
def _cap_width_to_window(self, desired_width: int) -> int:
|
|
1213
|
+
"""
|
|
1214
|
+
Cap desired popup width to the allowed width inside the parent window.
|
|
1215
|
+
|
|
1216
|
+
:param desired_width: desired popup width
|
|
1217
|
+
:return: capped width
|
|
1218
|
+
"""
|
|
1219
|
+
try:
|
|
1220
|
+
allowed = self._popup_allowed_rect()
|
|
1221
|
+
max_w = max(50, allowed.width())
|
|
1222
|
+
return max(50, min(desired_width, max_w))
|
|
1223
|
+
except Exception:
|
|
1224
|
+
return desired_width
|
|
1225
|
+
|
|
1226
|
+
def _fit_popup_to_window(self):
|
|
1227
|
+
"""
|
|
1228
|
+
Ensure popup container stays horizontally within the parent window:
|
|
1229
|
+
- clamp width to allowed rect,
|
|
1230
|
+
- shift left if right edge would overflow.
|
|
1231
|
+
"""
|
|
1232
|
+
if self._fit_in_progress:
|
|
1233
|
+
return
|
|
1234
|
+
view = self.view()
|
|
1235
|
+
container = self._popup_container or (view.window() if view is not None else None)
|
|
1236
|
+
if container is None:
|
|
1237
|
+
return
|
|
1238
|
+
try:
|
|
1239
|
+
self._fit_in_progress = True
|
|
1240
|
+
|
|
1241
|
+
allowed = self._popup_allowed_rect()
|
|
1242
|
+
|
|
1243
|
+
cg = container.geometry()
|
|
1244
|
+
y, h = cg.y(), cg.height()
|
|
1245
|
+
|
|
1246
|
+
# Determine target width: prefer the larger of container or combo width, but not over allowed.
|
|
1247
|
+
desired_w = max(cg.width(), self.width())
|
|
1248
|
+
target_w = self._cap_width_to_window(desired_w)
|
|
1249
|
+
|
|
1250
|
+
# Position: keep current left if possible, otherwise shift to keep right edge inside.
|
|
1251
|
+
left_allowed = allowed.x()
|
|
1252
|
+
right_allowed = allowed.x() + allowed.width()
|
|
1253
|
+
new_x = cg.x()
|
|
1254
|
+
if new_x + target_w > right_allowed:
|
|
1255
|
+
new_x = right_allowed - target_w
|
|
1256
|
+
if new_x < left_allowed:
|
|
1257
|
+
new_x = left_allowed
|
|
1258
|
+
|
|
1259
|
+
# Apply constraints to the internal view as well to avoid relayout expanding the container back
|
|
1260
|
+
try:
|
|
1261
|
+
if view is not None:
|
|
1262
|
+
if view.minimumWidth() > target_w:
|
|
1263
|
+
view.setMinimumWidth(target_w)
|
|
1264
|
+
view.setMaximumWidth(target_w)
|
|
1265
|
+
except Exception:
|
|
1266
|
+
pass
|
|
1267
|
+
|
|
1268
|
+
if cg.x() != new_x or cg.width() != target_w:
|
|
1269
|
+
container.setGeometry(new_x, y, target_w, h)
|
|
1270
|
+
|
|
1271
|
+
# Keep header sized to new width
|
|
1272
|
+
self._place_popup_header()
|
|
1273
|
+
except Exception:
|
|
1274
|
+
pass
|
|
1275
|
+
finally:
|
|
1276
|
+
self._fit_in_progress = False
|
|
1277
|
+
|
|
1122
1278
|
# ----- Internal helpers -----
|
|
1123
1279
|
|
|
1124
1280
|
def _refresh_popup_view(self, *_):
|
|
@@ -1146,7 +1302,7 @@ class NoScrollCombo(SearchableCombo):
|
|
|
1146
1302
|
event.ignore()
|
|
1147
1303
|
|
|
1148
1304
|
def showPopup(self):
|
|
1149
|
-
"""Adjust popup width to fit the longest item before showing."""
|
|
1305
|
+
"""Adjust popup width to fit the longest item before showing, capped to the window width."""
|
|
1150
1306
|
max_width = 0
|
|
1151
1307
|
font_metrics = QFontMetrics(self.font())
|
|
1152
1308
|
for i in range(self.count()):
|
|
@@ -1154,11 +1310,19 @@ class NoScrollCombo(SearchableCombo):
|
|
|
1154
1310
|
width = font_metrics.horizontalAdvance(text)
|
|
1155
1311
|
max_width = max(max_width, width)
|
|
1156
1312
|
extra_margin = 80
|
|
1157
|
-
max_width
|
|
1313
|
+
desired = max_width + extra_margin
|
|
1314
|
+
|
|
1315
|
+
# Cap desired width to parent window to avoid right overflow when window is not maximized
|
|
1316
|
+
capped = self._cap_width_to_window(desired)
|
|
1317
|
+
|
|
1158
1318
|
try:
|
|
1159
|
-
self.view()
|
|
1319
|
+
v = self.view()
|
|
1320
|
+
if v is not None:
|
|
1321
|
+
v.setMinimumWidth(capped)
|
|
1322
|
+
v.setMaximumWidth(capped)
|
|
1160
1323
|
except Exception:
|
|
1161
1324
|
pass
|
|
1325
|
+
|
|
1162
1326
|
super().showPopup()
|
|
1163
1327
|
|
|
1164
1328
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pygpt-net
|
|
3
|
-
Version: 2.7.
|
|
3
|
+
Version: 2.7.1
|
|
4
4
|
Summary: Desktop AI Assistant powered by: OpenAI GPT-5, GPT-4, o1, o3, Gemini, Claude, Grok, DeepSeek, and other models supported by Llama Index, and Ollama. Chatbot, agents, completion, image generation, vision analysis, speech-to-text, plugins, MCP, internet access, file handling, command execution and more.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: ai,api,api key,app,assistant,bielik,chat,chatbot,chatgpt,claude,dall-e,deepseek,desktop,gemini,gpt,gpt-3.5,gpt-4,gpt-4-vision,gpt-4o,gpt-5,gpt-oss,gpt3.5,gpt4,grok,langchain,llama-index,llama3,mistral,o1,o3,ollama,openai,presets,py-gpt,py_gpt,pygpt,pyside,qt,text completion,tts,ui,vision,whisper
|
|
@@ -119,7 +119,7 @@ Description-Content-Type: text/markdown
|
|
|
119
119
|
|
|
120
120
|
[](https://snapcraft.io/pygpt)
|
|
121
121
|
|
|
122
|
-
Release: **2.7.
|
|
122
|
+
Release: **2.7.1** | build: **2025-12-28** | Python: **>=3.10, <3.14**
|
|
123
123
|
|
|
124
124
|
> Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
|
|
125
125
|
>
|
|
@@ -3753,6 +3753,14 @@ may consume additional tokens that are not displayed in the main window.
|
|
|
3753
3753
|
|
|
3754
3754
|
## Recent changes:
|
|
3755
3755
|
|
|
3756
|
+
**2.7.1 (2025-12-28)**
|
|
3757
|
+
|
|
3758
|
+
- Improved UI elements.
|
|
3759
|
+
- Optimized Painter rendering and redraw functions.
|
|
3760
|
+
- Added Pack/Unpack feature to File Explorer.
|
|
3761
|
+
- Fixed: image restoration in Painter.
|
|
3762
|
+
- Fixed: tab title updating upon context deletion.
|
|
3763
|
+
|
|
3756
3764
|
**2.7.0 (2025-12-28)**
|
|
3757
3765
|
|
|
3758
3766
|
- Added multi-select functionality using CTRL or SHIFT and batch actions to the context list, preset list, attachments list, and other list-based widgets.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
pygpt_net/CHANGELOG.txt,sha256=
|
|
1
|
+
pygpt_net/CHANGELOG.txt,sha256=7IWjxZ4U7vrkz7Rm11SYVlx86JVVvPuB9KlnlE5g9CE,111266
|
|
2
2
|
pygpt_net/LICENSE,sha256=dz9sfFgYahvu2NZbx4C1xCsVn9GVer2wXcMkFRBvqzY,1146
|
|
3
|
-
pygpt_net/__init__.py,sha256=
|
|
3
|
+
pygpt_net/__init__.py,sha256=HE-0lPnwAxTlfnrMK-HgSrmc0jBRQPs0VqekO_IUv2o,1372
|
|
4
4
|
pygpt_net/app.py,sha256=W-2rCYLndMgVV7cZZqeloqzifCggjISrFdMhHg0dMvM,23419
|
|
5
5
|
pygpt_net/app_core.py,sha256=PwBOV9wZLtr-O6SxBiazABhYXMHH8kZ6OgbvSv2OiZA,3827
|
|
6
6
|
pygpt_net/config.py,sha256=3CA7xXPKQsdRie1CY8_b5-Kk1taWMciUP9CesXRQNNY,18302
|
|
@@ -73,7 +73,7 @@ pygpt_net/controller/config/field/textarea.py,sha256=yhP0edUXlnmCEAkqevoeFqrBdtZ
|
|
|
73
73
|
pygpt_net/controller/config/placeholder.py,sha256=-PWPNILPVkxMsY64aYnKTWvgUIvx7KA2Nwfd2LW_K30,16711
|
|
74
74
|
pygpt_net/controller/ctx/__init__.py,sha256=0wH7ziC75WscBW8cxpeGBwEz5tolo_kCxGPoz2udI_E,507
|
|
75
75
|
pygpt_net/controller/ctx/common.py,sha256=C0Nz2f3PlWkg2Z7wwT-poiDlwdEbQWF6QGC5xcs4sTg,6904
|
|
76
|
-
pygpt_net/controller/ctx/ctx.py,sha256=
|
|
76
|
+
pygpt_net/controller/ctx/ctx.py,sha256=iQnAITxXeYf5DIyUzk1Uej9xg-fEznBNXjVbUPEsM-g,49708
|
|
77
77
|
pygpt_net/controller/ctx/extra.py,sha256=0r-G6Tlm9WPDkLRmgPDlgyRr_XLfCJntnUGlYPJiXVw,8598
|
|
78
78
|
pygpt_net/controller/ctx/summarizer.py,sha256=UNsq-JTARblGNT97uSMpZEVzdUuDJ8YA2j2dw9R2X3o,3079
|
|
79
79
|
pygpt_net/controller/debug/__init__.py,sha256=dOJGTICjvTtrPIEDOsxCzcOHsfu8AFPLpSKbdN0q0KI,509
|
|
@@ -119,7 +119,7 @@ pygpt_net/controller/notepad/__init__.py,sha256=ZbMh4D6nsGuI4AwYMdegfij5ubmUznEE
|
|
|
119
119
|
pygpt_net/controller/notepad/notepad.py,sha256=x1KBbZxIZls01ek4iOP9sCTMB6rk1_qNbAbPbWVIDFM,11110
|
|
120
120
|
pygpt_net/controller/painter/__init__.py,sha256=ZNZE6YcKprDPqLK5kiwtcJVvcW3H-YkerFW0PwbeQ1Y,511
|
|
121
121
|
pygpt_net/controller/painter/capture.py,sha256=X3TqnNypxT_wngkQ4ovfS9glQwoGHyM-peR5aLJQGvk,6666
|
|
122
|
-
pygpt_net/controller/painter/common.py,sha256=
|
|
122
|
+
pygpt_net/controller/painter/common.py,sha256=Jp4vGVgq52fq4Hy4D6hqniopmegWkMLwvbROU354Zac,16523
|
|
123
123
|
pygpt_net/controller/painter/painter.py,sha256=-qmVxxmsL_5aQs_DVoMLe0m6xZLIvijcItG4J1XHVfo,2866
|
|
124
124
|
pygpt_net/controller/plugins/__init__.py,sha256=iocY37De1H2Nh7HkC7ZYvUus2xzcckslgr5a4PwtQII,511
|
|
125
125
|
pygpt_net/controller/plugins/plugins.py,sha256=2y__KawXRKCKD-UR4yFnwJxo9bERfOUFBLpxhFLm7gA,16161
|
|
@@ -287,9 +287,9 @@ pygpt_net/core/experts/worker.py,sha256=KdVJv0ovjJ9oJ0Gj79m35JxiQbAxNPcQ5hUnqxG7
|
|
|
287
287
|
pygpt_net/core/filesystem/__init__.py,sha256=KZLS3s_otd3Md9eDA6FN-b4CtOCWl_fplUlM9V6hTy8,514
|
|
288
288
|
pygpt_net/core/filesystem/actions.py,sha256=mGvNDg8vr6E4rISIjguzJqb00lazsq4_-TN0V0b4qgs,7625
|
|
289
289
|
pygpt_net/core/filesystem/editor.py,sha256=or7cT2xhZfDwjX47reyXQCt-_1c4h_xPJDddYi1auNw,4284
|
|
290
|
-
pygpt_net/core/filesystem/filesystem.py,sha256
|
|
290
|
+
pygpt_net/core/filesystem/filesystem.py,sha256=-wds_6cwZvcG6426w4lUvX0z919Kt2GIYI8ffdKDv40,18385
|
|
291
291
|
pygpt_net/core/filesystem/opener.py,sha256=8EkieR_FwSz0HBykLcmV8TEw8Bn0e7WHqqiPTkDPp-M,7851
|
|
292
|
-
pygpt_net/core/filesystem/packer.py,sha256=
|
|
292
|
+
pygpt_net/core/filesystem/packer.py,sha256=aXxdxaoFmFjN1QCBkyXyh1_61H_-8pCGVzoSsRh_iBY,8435
|
|
293
293
|
pygpt_net/core/filesystem/parser.py,sha256=CLESCdASVQ1-cJ_6ZxbgDSxvwC-haznj_coE1_tWaQE,3548
|
|
294
294
|
pygpt_net/core/filesystem/types.py,sha256=1HFubxAHYup_SLQ7SlR5EvZb3KgVyd8K8vBRUkTcqaA,3458
|
|
295
295
|
pygpt_net/core/filesystem/url.py,sha256=0eT7QbRQw-G19oxG3AwKgREU2CsaLSF8Fw-IO04CvUU,3676
|
|
@@ -314,7 +314,7 @@ pygpt_net/core/idx/ui/__init__.py,sha256=nfCat59itYOlE7hgn-Y5iemtkgU2NWSnKZK_ffZ
|
|
|
314
314
|
pygpt_net/core/idx/ui/loaders.py,sha256=15-5Q5C9jGcLZkNkcqZDfAsQqwzLCZOFzHXCTGiYN6k,8732
|
|
315
315
|
pygpt_net/core/idx/worker.py,sha256=c6sywqK9U0p3kFFf94MUoqM8XIYJUAnIBTDJzU-XqfI,4428
|
|
316
316
|
pygpt_net/core/image/__init__.py,sha256=HEXciv02RFJC3BkrzP9tvzvZlr36WYMz5v9W80JLqlQ,509
|
|
317
|
-
pygpt_net/core/image/image.py,sha256=
|
|
317
|
+
pygpt_net/core/image/image.py,sha256=VKnLN1bHpFatwN3YfAVHnWTF58S4L-AyrwgPODCmSYs,6450
|
|
318
318
|
pygpt_net/core/info/__init__.py,sha256=SJUPrGXxdvHTpM3AyvsaD_Z_Fuzrg2cbcNevB7A6X-8,508
|
|
319
319
|
pygpt_net/core/info/info.py,sha256=YJEDJnGVMmMp0sQ0tEDyri6Kr94CopcZF6L97w9dXDg,829
|
|
320
320
|
pygpt_net/core/installer/__init__.py,sha256=ReDXTveTr-U9brtM1bbtdC5vU92Jjo6mVvc7bfwQl_I,513
|
|
@@ -406,7 +406,7 @@ pygpt_net/core/types/tools.py,sha256=BdonNwytk5SxYtYdlDkMg5lMvFoXz3CQJHZ__oVlm_8
|
|
|
406
406
|
pygpt_net/core/updater/__init__.py,sha256=fC4g0Xn9S8lLxGbop1q2o2qi9IZegoVayNVWemgBwds,511
|
|
407
407
|
pygpt_net/core/updater/updater.py,sha256=RArlEaYWNw5PIKcG2hMWqZI3DLbi8vq7Ip_rc8TBBNI,17045
|
|
408
408
|
pygpt_net/core/video/__init__.py,sha256=PBAsunvkPSJJvcx2XivIul96XsbcW8mPAda_CX3dK1U,513
|
|
409
|
-
pygpt_net/core/video/video.py,sha256
|
|
409
|
+
pygpt_net/core/video/video.py,sha256=-EUt5halPea0I77oktZqoVCw0mmpDMbUX20gUb7FYfI,10078
|
|
410
410
|
pygpt_net/core/vision/__init__.py,sha256=dFEilXM2Z128SmgBlLn1DvyLCksdcyqFI7rln_VPsf8,510
|
|
411
411
|
pygpt_net/core/vision/analyzer.py,sha256=kzIBRhYrsPz3GD7ekN6GmQoF_f2e1w3WyVDnhse2s0g,4626
|
|
412
412
|
pygpt_net/core/vision/vision.py,sha256=JX_tazW31Xesd6nPY1I1UcGmPd_V0hCG3JfMYW06oHo,728
|
|
@@ -420,8 +420,8 @@ pygpt_net/css_rc.py,sha256=PX6g9z5BsD-DXISuR2oq3jHcjiKfcJ4HsgcHez6wGMc,27762
|
|
|
420
420
|
pygpt_net/data/audio/click_off.mp3,sha256=aNiRDP1pt-Jy7ija4YKCNFBwvGWbzU460F4pZWZDS90,65201
|
|
421
421
|
pygpt_net/data/audio/click_on.mp3,sha256=qfdsSnthAEHVXzeyN4LlC0OvXuyW8p7stb7VXtlvZ1k,65201
|
|
422
422
|
pygpt_net/data/audio/ok.mp3,sha256=LTiV32pEBkpUGBkKkcOdOFB7Eyt_QoP2Nv6c5AaXftk,32256
|
|
423
|
-
pygpt_net/data/config/config.json,sha256=
|
|
424
|
-
pygpt_net/data/config/models.json,sha256=
|
|
423
|
+
pygpt_net/data/config/config.json,sha256=rv9pIgW5IdvTirnfEPGnYOFYCsgkEeFvqxbKIM6SHRY,30935
|
|
424
|
+
pygpt_net/data/config/models.json,sha256=zrESWVgJiPu5njHiaaxEaZH05BF54i9pIgN81DRJM_0,135705
|
|
425
425
|
pygpt_net/data/config/modes.json,sha256=IpjLOm428_vs6Ma9U-YQTNKJNtZw-qyM1lwhh73xl1w,2111
|
|
426
426
|
pygpt_net/data/config/presets/agent_code_act.json,sha256=GYHqhxtKFLUCvRI3IJAJ7Qe1k8yD9wGGNwManldWzlI,754
|
|
427
427
|
pygpt_net/data/config/presets/agent_openai.json,sha256=bpDJgLRey_effQkzFRoOEGd4aHUrmzeODSDdNzrf62I,730
|
|
@@ -465,8 +465,8 @@ pygpt_net/data/css/markdown.css,sha256=yaoJPogZZ_ghbqP8vTXTycwVyD61Ik5_033NpzuUz
|
|
|
465
465
|
pygpt_net/data/css/markdown.dark.css,sha256=ixAwuT69QLesZttKhO4RAy-QukplZwwfXCZsWLN9TP4,730
|
|
466
466
|
pygpt_net/data/css/markdown.light.css,sha256=UZdv0jtuFgJ_4bYWsDaDQ4X4AP9tVNLUHBAckC_oD8k,833
|
|
467
467
|
pygpt_net/data/css/style.css,sha256=dgVlVqEL38zF-4Ok-y1rwfALC8zETJAIuIbkwat_hTk,337
|
|
468
|
-
pygpt_net/data/css/style.dark.css,sha256=
|
|
469
|
-
pygpt_net/data/css/style.light.css,sha256=
|
|
468
|
+
pygpt_net/data/css/style.dark.css,sha256=_N9UYcU7XHcXBaRsknie0NibiS6CfvbKYgogtHkYH5I,4132
|
|
469
|
+
pygpt_net/data/css/style.light.css,sha256=Zf8AV0uE1vg2Dum7fRHkfGhJf_WBLM5DnHx8zYYfxYg,6470
|
|
470
470
|
pygpt_net/data/css/web-blocks.css,sha256=i8BwIwauKvKiWq3bte45R6_bI6bjFyjKyshkTb2JWgs,7598
|
|
471
471
|
pygpt_net/data/css/web-blocks.dark.css,sha256=mck2u9KiO-pvnms0N0XJkoM_RBuf8QdC_3iSWAg8r40,1855
|
|
472
472
|
pygpt_net/data/css/web-blocks.darkest.css,sha256=p3929omAaS1yxNtcOk9yR6cdVGkTVLCIyVsmltxLVf4,1807
|
|
@@ -1730,14 +1730,14 @@ pygpt_net/data/js/katex/katex.min.js,sha256=KLASOtKS2x8pUxWVzCDmlWJ4jhuLb0vtrgak
|
|
|
1730
1730
|
pygpt_net/data/js/markdown-it/markdown-it-katex.min.js,sha256=-wMst2a9i8Borapa9_hxPvpQysfFE-yph8GrBmDoA68,1670
|
|
1731
1731
|
pygpt_net/data/js/markdown-it/markdown-it.min.js,sha256=OMcKHnypGrQOLZ5uYBKYUacX7Rx9Ssu91Bv5UDeRz2g,123618
|
|
1732
1732
|
pygpt_net/data/languages.csv,sha256=fvtER6vnTXFHQslCh-e0xCfZDQ-ijgW4GYpOJG4U7LY,8289
|
|
1733
|
-
pygpt_net/data/locale/locale.de.ini,sha256=
|
|
1734
|
-
pygpt_net/data/locale/locale.en.ini,sha256=
|
|
1735
|
-
pygpt_net/data/locale/locale.es.ini,sha256=
|
|
1736
|
-
pygpt_net/data/locale/locale.fr.ini,sha256=
|
|
1737
|
-
pygpt_net/data/locale/locale.it.ini,sha256=
|
|
1738
|
-
pygpt_net/data/locale/locale.pl.ini,sha256=
|
|
1739
|
-
pygpt_net/data/locale/locale.uk.ini,sha256=
|
|
1740
|
-
pygpt_net/data/locale/locale.zh.ini,sha256=
|
|
1733
|
+
pygpt_net/data/locale/locale.de.ini,sha256=rLvE1O4mB9_3CAKZpzgZ9w0C5bjQ0XODgBheVlr2tq0,112664
|
|
1734
|
+
pygpt_net/data/locale/locale.en.ini,sha256=katEw0ZBZyU9LhYKFViMunA4mUmP3k-NwaTGmb-fZjg,106756
|
|
1735
|
+
pygpt_net/data/locale/locale.es.ini,sha256=4IyNjd3AesvVlHlIWyWNoAP04Rd1pdQFDZzDRIqqHjk,113211
|
|
1736
|
+
pygpt_net/data/locale/locale.fr.ini,sha256=XMCFZc4fpv-H4BdZgIiv6Gr9HUxaMrHWPl6fV_2L_Jc,116077
|
|
1737
|
+
pygpt_net/data/locale/locale.it.ini,sha256=u5QVLrtZ9A3-2oDijuWOS7Yp8aNmQ7rBmzH_XF8qXDY,110897
|
|
1738
|
+
pygpt_net/data/locale/locale.pl.ini,sha256=aqeNHvTGRp0d8Bm3wJBxbLE-ahpHkgfJ9Tip54QwzW8,110578
|
|
1739
|
+
pygpt_net/data/locale/locale.uk.ini,sha256=XF6CL_W_fIyQ6o7kTq1j9bAQCXl8jMDCa-UsIgGrrGc,154096
|
|
1740
|
+
pygpt_net/data/locale/locale.zh.ini,sha256=KAdfNXxlAOfaIafBGt9yb-mq12ioSMmOSOR4i7iv3zQ,98935
|
|
1741
1741
|
pygpt_net/data/locale/plugin.agent.de.ini,sha256=BY28KpfFvgfVYJzcw2o5ScWnR4uuErIYGyc3NVHlmTw,1714
|
|
1742
1742
|
pygpt_net/data/locale/plugin.agent.en.ini,sha256=HwOWCI7e8uzlIgyRWRVyr1x6Xzs8Xjv5pfEc7jfLOo4,1728
|
|
1743
1743
|
pygpt_net/data/locale/plugin.agent.es.ini,sha256=bqaJQne8HPKFVtZ8Ukzo1TSqVW41yhYbGUqW3j2x1p8,1680
|
|
@@ -2250,7 +2250,7 @@ pygpt_net/provider/core/calendar/db_sqlite/storage.py,sha256=QDclQCQdr4QyRIqjgGX
|
|
|
2250
2250
|
pygpt_net/provider/core/config/__init__.py,sha256=jQQgG9u_ZLsZWXustoc1uvC-abUvj4RBKPAM30-f2Kc,488
|
|
2251
2251
|
pygpt_net/provider/core/config/base.py,sha256=cbvzbMNqL2XgC-36gGubnU37t94AX7LEw0lecb2Nm80,1365
|
|
2252
2252
|
pygpt_net/provider/core/config/json_file.py,sha256=GCcpCRQnBiSLWwlGbG9T3ZgiHkTfp5Jsg2KYkZcakBw,6789
|
|
2253
|
-
pygpt_net/provider/core/config/patch.py,sha256=
|
|
2253
|
+
pygpt_net/provider/core/config/patch.py,sha256=r73m4AOulhoS-8sXAaQpjiWy7TfTaj7WV7CHV9BzA2g,8535
|
|
2254
2254
|
pygpt_net/provider/core/config/patches/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2255
2255
|
pygpt_net/provider/core/config/patches/patch_before_2_6_42.py,sha256=_IcpB3DdiD01P2_jpt2ZvUs8WJRIeO6t5oQeNxY6_eE,126808
|
|
2256
2256
|
pygpt_net/provider/core/ctx/__init__.py,sha256=jQQgG9u_ZLsZWXustoc1uvC-abUvj4RBKPAM30-f2Kc,488
|
|
@@ -2488,7 +2488,7 @@ pygpt_net/ui/dialog/logger.py,sha256=OGFKlAyeMgNQI4a-VW9bDXSrcsPtEC6rLhtdu11lsJc
|
|
|
2488
2488
|
pygpt_net/ui/dialog/models.py,sha256=kog8P4O061LetxHTJARwrQxXu3so_xkhMK31iC-Ceog,20376
|
|
2489
2489
|
pygpt_net/ui/dialog/models_importer.py,sha256=14kxf7KkOdTP-tcgTN5OphNZajlivDPTDKBosebuyog,4505
|
|
2490
2490
|
pygpt_net/ui/dialog/plugins.py,sha256=88TsvYWHdmR5hepld6ouSEa4BDhewAQ-JFE7RWGSdy8,20287
|
|
2491
|
-
pygpt_net/ui/dialog/preset.py,sha256=
|
|
2491
|
+
pygpt_net/ui/dialog/preset.py,sha256=LQbhA1u9tt64DAbqsjQgc-tpqffzesR0wmikBiRODbY,20592
|
|
2492
2492
|
pygpt_net/ui/dialog/preset_plugins.py,sha256=ynqc0aWjU7MTL4jxcVKaRH_tC9uzeWJCUzUjI74ADb0,3796
|
|
2493
2493
|
pygpt_net/ui/dialog/profile.py,sha256=Xk9NNQmr1A5pRUxdedu7ePEBq5OYhLT8UInuRWYBktU,4105
|
|
2494
2494
|
pygpt_net/ui/dialog/rename.py,sha256=Spb7cUVq1ivy3Zg28SBACJ7p_GwJ1gm82Oz9Ld_a_FU,973
|
|
@@ -2524,8 +2524,8 @@ pygpt_net/ui/layout/toolbox/assistants.py,sha256=pZ_jOo4-Khqbm04rJuvENVZ5AUhXDUK
|
|
|
2524
2524
|
pygpt_net/ui/layout/toolbox/audio.py,sha256=8k2qYzVmSv6g0KXhQBY9_diuGBPODSe7VHiEBpsCzUU,2030
|
|
2525
2525
|
pygpt_net/ui/layout/toolbox/computer_env.py,sha256=QP_Qv4X28ineVX4vFfykmV-RDjgJpQp_oBHne3R4zY4,2210
|
|
2526
2526
|
pygpt_net/ui/layout/toolbox/footer.py,sha256=LbLDXbcarPfH-tpBKgXlQqkAvm1HcNZpR7fPjbD76KA,4278
|
|
2527
|
-
pygpt_net/ui/layout/toolbox/image.py,sha256=
|
|
2528
|
-
pygpt_net/ui/layout/toolbox/indexes.py,sha256=
|
|
2527
|
+
pygpt_net/ui/layout/toolbox/image.py,sha256=NjAcyUaLmQp8M18vc2Z4Aq0nGQp-BRMgZEaC4qXHzSE,1974
|
|
2528
|
+
pygpt_net/ui/layout/toolbox/indexes.py,sha256=GfiQ-DA-mE-fr_1P5r-8jeMJ_LeQR9PvpH5oo4oBEwc,6882
|
|
2529
2529
|
pygpt_net/ui/layout/toolbox/mode.py,sha256=MfVunjZZ3Wi0o4sbWBqg74c2-W6BNDHr3ylZevLZb8c,2085
|
|
2530
2530
|
pygpt_net/ui/layout/toolbox/model.py,sha256=OxcxSyFCQ3z6XAwj991X4KiSb78Upfn4v4m3991yvsw,1707
|
|
2531
2531
|
pygpt_net/ui/layout/toolbox/presets.py,sha256=dOpZBcbE6ygIOjLrj-O5O0Cj6IIoH7Y5SerOYmBTpI4,8150
|
|
@@ -2533,7 +2533,7 @@ pygpt_net/ui/layout/toolbox/prompt.py,sha256=subUUZJgkCmvSRekZcgVYs6wzl-MYPBLXKT
|
|
|
2533
2533
|
pygpt_net/ui/layout/toolbox/raw.py,sha256=Uvkk0QnrOIZ9sHJ3EnDzTRaWDLNC6cdgYyICPI8lJCk,1803
|
|
2534
2534
|
pygpt_net/ui/layout/toolbox/split.py,sha256=Hs9hZPciLXCRV_izoayrBlJSCuTGumdNki6z1giWUUo,1696
|
|
2535
2535
|
pygpt_net/ui/layout/toolbox/toolbox.py,sha256=VHzyzm7LjcAN30h111SEP6fdXwi84DYyf8CE1X3pdt8,2799
|
|
2536
|
-
pygpt_net/ui/layout/toolbox/video.py,sha256=
|
|
2536
|
+
pygpt_net/ui/layout/toolbox/video.py,sha256=2XmLlFns53H65xd_9RaIkCrOdh-ZKQ96MssHgvVaaM0,2197
|
|
2537
2537
|
pygpt_net/ui/layout/toolbox/vision.py,sha256=E6-lLfU3vrWdlprayr6gxFs7F7AGkn4OIrFXrQ9p5XA,2035
|
|
2538
2538
|
pygpt_net/ui/main.py,sha256=PYPVQf_5l3CVdsTB7S4lmO3Qs3aEVYhtwuXeOQeGFsM,14311
|
|
2539
2539
|
pygpt_net/ui/menu/__init__.py,sha256=wAIKG9wLWfYv6tpXCTXptWb_XKoCc-4lYWLDvV1bVYk,508
|
|
@@ -2588,7 +2588,7 @@ pygpt_net/ui/widget/dialog/update.py,sha256=YGUouxuEqvO8rkjI52F7wG4R8OgqcpJKB1FV
|
|
|
2588
2588
|
pygpt_net/ui/widget/dialog/url.py,sha256=7I17Pp9P2c3G1pODEY5dum_AF0nFnu2BMfbWTgEES-M,8765
|
|
2589
2589
|
pygpt_net/ui/widget/dialog/workdir.py,sha256=D-C3YIt-wCoI-Eh7z--Z4R6P1UvtpkxeiaVcI-ycFck,1523
|
|
2590
2590
|
pygpt_net/ui/widget/draw/__init__.py,sha256=oSYKtNEGNL0vDjn3wCgdnBAbxUqNGIEIf-75I2DIn7Q,488
|
|
2591
|
-
pygpt_net/ui/widget/draw/painter.py,sha256=
|
|
2591
|
+
pygpt_net/ui/widget/draw/painter.py,sha256=oiIrNos6SGLCCFeqEHFLy9hyccQIOQCQwFhVjt_-fYw,60212
|
|
2592
2592
|
pygpt_net/ui/widget/element/__init__.py,sha256=8HT4tQFqQogEEpGYTv2RplKBthlsFKcl5egnv4lzzEw,488
|
|
2593
2593
|
pygpt_net/ui/widget/element/button.py,sha256=rhy8_RVHRV8xl0pegul31z9fNBjjIAi5Nd0hHGF6cF8,4393
|
|
2594
2594
|
pygpt_net/ui/widget/element/checkbox.py,sha256=qyX6T31c3a8Wb8B4JZwhuejD9SUAFSesdIjZdj4tv8I,2948
|
|
@@ -2596,7 +2596,7 @@ pygpt_net/ui/widget/element/group.py,sha256=9wedtjRTls4FdyHSwUblzdtPOaQ0-8djnjTN
|
|
|
2596
2596
|
pygpt_net/ui/widget/element/labels.py,sha256=C16DWoWzSt-VFnfLM5Yg7NiM1iVZj6DyttoIShely84,6749
|
|
2597
2597
|
pygpt_net/ui/widget/element/status.py,sha256=csRP1xzqB2yNyW2wdYQdGy7VVvzBucKHzjZ0DTHI-Q8,1773
|
|
2598
2598
|
pygpt_net/ui/widget/filesystem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2599
|
-
pygpt_net/ui/widget/filesystem/explorer.py,sha256=
|
|
2599
|
+
pygpt_net/ui/widget/filesystem/explorer.py,sha256=T-0cQ-jwmlYglo2gKjaj02Q0V5Z6XMiztCB7nqf2rAQ,68297
|
|
2600
2600
|
pygpt_net/ui/widget/image/__init__.py,sha256=X9-pucLqQF9_ocDV-qNY6EQAJ_4dubGb-7TcWIzCXBo,488
|
|
2601
2601
|
pygpt_net/ui/widget/image/display.py,sha256=73lBXCdmdAxjCCD2XV3HBdvYU6PgL_PpybweONMOSik,3771
|
|
2602
2602
|
pygpt_net/ui/widget/lists/__init__.py,sha256=8HT4tQFqQogEEpGYTv2RplKBthlsFKcl5egnv4lzzEw,488
|
|
@@ -2638,7 +2638,7 @@ pygpt_net/ui/widget/option/__init__.py,sha256=8HT4tQFqQogEEpGYTv2RplKBthlsFKcl5e
|
|
|
2638
2638
|
pygpt_net/ui/widget/option/checkbox.py,sha256=duzgGPOVbHFnWILVEu5gDUa6sHeDOvQaaj9IsY-HbU8,3954
|
|
2639
2639
|
pygpt_net/ui/widget/option/checkbox_list.py,sha256=SgnkLTlVZCcU3ehqAfi_w28x693w_AeNsK-_0k-uOwA,6198
|
|
2640
2640
|
pygpt_net/ui/widget/option/cmd.py,sha256=Ii_i9hR4oRmG4-TPZ-FHuTv3I1vL96YLcDP2QSKmAbI,5800
|
|
2641
|
-
pygpt_net/ui/widget/option/combo.py,sha256=
|
|
2641
|
+
pygpt_net/ui/widget/option/combo.py,sha256=gU6kNDEg7RgKxxhPkhjjuUVGHY_BJkVqL4l-UeqD_Jk,53852
|
|
2642
2642
|
pygpt_net/ui/widget/option/dictionary.py,sha256=ZeaBk-wEZ0SBU_iBBL6eHUEIGOrahh-z2xTa7LBvsdM,14736
|
|
2643
2643
|
pygpt_net/ui/widget/option/input.py,sha256=-pLXzkOO2OvOoUKTuocbOt8JcPWQO3W3cmrSh0WhJcc,9718
|
|
2644
2644
|
pygpt_net/ui/widget/option/prompt.py,sha256=SgRd0acp13_c19tWjYYChcGgAwik9tsZKKsX1Ciqgp4,2818
|
|
@@ -2669,8 +2669,8 @@ pygpt_net/ui/widget/textarea/web.py,sha256=sVRSmudPwPfjK2h7q-e6Ae4b-677BHLe20t-x
|
|
|
2669
2669
|
pygpt_net/ui/widget/vision/__init__.py,sha256=8HT4tQFqQogEEpGYTv2RplKBthlsFKcl5egnv4lzzEw,488
|
|
2670
2670
|
pygpt_net/ui/widget/vision/camera.py,sha256=DCx7h1nHruuUkU0Tw8Ay4OUVoNJhkuLsW4hIvGF5Skw,6985
|
|
2671
2671
|
pygpt_net/utils.py,sha256=r-Dum4brfBaZaHJr-ux86FfdMuMHFwyuUL2bEFirdhc,14649
|
|
2672
|
-
pygpt_net-2.7.
|
|
2673
|
-
pygpt_net-2.7.
|
|
2674
|
-
pygpt_net-2.7.
|
|
2675
|
-
pygpt_net-2.7.
|
|
2676
|
-
pygpt_net-2.7.
|
|
2672
|
+
pygpt_net-2.7.1.dist-info/LICENSE,sha256=rbPqNB_xxANH8hKayJyIcTwD4bj4Y2G-Mcm85r1OImM,1126
|
|
2673
|
+
pygpt_net-2.7.1.dist-info/METADATA,sha256=0kgOzOlnrDmM8eCA-BKS7HtYyKGVUKbaa7n7owqRR-8,169942
|
|
2674
|
+
pygpt_net-2.7.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
2675
|
+
pygpt_net-2.7.1.dist-info/entry_points.txt,sha256=qvpII6UHIt8XfokmQWnCYQrTgty8FeJ9hJvOuUFCN-8,43
|
|
2676
|
+
pygpt_net-2.7.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|