pygpt-net 2.6.60__py3-none-any.whl → 2.6.61__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.
Files changed (60) hide show
  1. pygpt_net/CHANGELOG.txt +7 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/controller/chat/common.py +115 -6
  4. pygpt_net/controller/chat/input.py +4 -1
  5. pygpt_net/controller/presets/presets.py +121 -6
  6. pygpt_net/controller/settings/editor.py +0 -15
  7. pygpt_net/controller/theme/markdown.py +2 -5
  8. pygpt_net/controller/ui/ui.py +4 -7
  9. pygpt_net/core/agents/custom/__init__.py +7 -1
  10. pygpt_net/core/agents/custom/llama_index/factory.py +17 -6
  11. pygpt_net/core/agents/custom/llama_index/runner.py +35 -2
  12. pygpt_net/core/agents/custom/llama_index/utils.py +12 -1
  13. pygpt_net/core/agents/custom/router.py +45 -6
  14. pygpt_net/core/agents/custom/runner.py +2 -1
  15. pygpt_net/core/agents/custom/schema.py +3 -1
  16. pygpt_net/core/agents/custom/utils.py +13 -1
  17. pygpt_net/core/db/viewer.py +11 -5
  18. pygpt_net/core/node_editor/graph.py +18 -9
  19. pygpt_net/core/node_editor/models.py +9 -2
  20. pygpt_net/core/node_editor/types.py +3 -1
  21. pygpt_net/core/presets/presets.py +216 -29
  22. pygpt_net/core/render/markdown/parser.py +0 -2
  23. pygpt_net/data/config/config.json +5 -6
  24. pygpt_net/data/config/models.json +3 -3
  25. pygpt_net/data/config/settings.json +2 -38
  26. pygpt_net/data/locale/locale.de.ini +64 -1
  27. pygpt_net/data/locale/locale.en.ini +62 -3
  28. pygpt_net/data/locale/locale.es.ini +64 -1
  29. pygpt_net/data/locale/locale.fr.ini +64 -1
  30. pygpt_net/data/locale/locale.it.ini +64 -1
  31. pygpt_net/data/locale/locale.pl.ini +65 -2
  32. pygpt_net/data/locale/locale.uk.ini +64 -1
  33. pygpt_net/data/locale/locale.zh.ini +64 -1
  34. pygpt_net/data/locale/plugin.cmd_system.en.ini +62 -66
  35. pygpt_net/provider/agents/llama_index/flow_from_schema.py +2 -2
  36. pygpt_net/provider/core/config/patch.py +10 -1
  37. pygpt_net/provider/core/config/patches/patch_before_2_6_42.py +0 -6
  38. pygpt_net/tools/agent_builder/tool.py +42 -26
  39. pygpt_net/tools/agent_builder/ui/dialogs.py +60 -11
  40. pygpt_net/ui/__init__.py +2 -4
  41. pygpt_net/ui/dialog/about.py +58 -38
  42. pygpt_net/ui/dialog/db.py +142 -3
  43. pygpt_net/ui/dialog/preset.py +47 -8
  44. pygpt_net/ui/layout/toolbox/presets.py +52 -16
  45. pygpt_net/ui/widget/dialog/db.py +0 -0
  46. pygpt_net/ui/widget/lists/preset.py +644 -60
  47. pygpt_net/ui/widget/node_editor/command.py +10 -10
  48. pygpt_net/ui/widget/node_editor/config.py +157 -0
  49. pygpt_net/ui/widget/node_editor/editor.py +183 -151
  50. pygpt_net/ui/widget/node_editor/item.py +12 -11
  51. pygpt_net/ui/widget/node_editor/node.py +267 -12
  52. pygpt_net/ui/widget/node_editor/view.py +180 -63
  53. pygpt_net/ui/widget/tabs/output.py +1 -1
  54. pygpt_net/ui/widget/textarea/input.py +2 -2
  55. pygpt_net/utils.py +114 -2
  56. {pygpt_net-2.6.60.dist-info → pygpt_net-2.6.61.dist-info}/METADATA +11 -94
  57. {pygpt_net-2.6.60.dist-info → pygpt_net-2.6.61.dist-info}/RECORD +59 -58
  58. {pygpt_net-2.6.60.dist-info → pygpt_net-2.6.61.dist-info}/LICENSE +0 -0
  59. {pygpt_net-2.6.60.dist-info → pygpt_net-2.6.61.dist-info}/WHEEL +0 -0
  60. {pygpt_net-2.6.60.dist-info → pygpt_net-2.6.61.dist-info}/entry_points.txt +0 -0
@@ -6,11 +6,11 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.09.05 18:00:00 #
9
+ # Updated Date: 2025.09.26 03:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6 import QtCore
13
- from PySide6.QtGui import QStandardItemModel, Qt, QIcon
13
+ from PySide6.QtGui import QStandardItemModel, QStandardItem, Qt, QIcon
14
14
  from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QPushButton, QWidget, QSizePolicy
15
15
 
16
16
  from pygpt_net.core.types import (
@@ -113,35 +113,42 @@ class Presets:
113
113
  nodes = self.window.ui.nodes
114
114
  models = self.window.ui.models
115
115
 
116
- view = nodes[self.id]
116
+ view: PresetList = nodes[self.id]
117
117
  model = models.get(self.id)
118
118
 
119
- view.backup_selection()
119
+ # If view requested selection override, do NOT override it by backup
120
+ selection_override_ids = getattr(view, "_selection_override_ids", None)
121
+ if not selection_override_ids:
122
+ view.backup_selection()
120
123
 
121
124
  if model is None:
122
125
  model = self.create_model(self.window)
123
126
  models[self.id] = model
124
127
  view.setModel(model)
125
128
 
129
+ # Block user input during model rebuild to avoid crashes on quick clicks
130
+ view.begin_model_update()
131
+
132
+ # Turn off updates to avoid flicker and transient artifacts
126
133
  view.setUpdatesEnabled(False)
127
134
  try:
128
- if not data:
129
- model.setRowCount(0)
130
- else:
131
- count = len(data)
132
- model.setRowCount(count)
135
+ # Rebuild model cleanly to avoid any stale items causing visual glitches
136
+ model.clear()
137
+ model.setColumnCount(1)
133
138
 
139
+ if data:
134
140
  is_expert_mode = (mode == MODE_EXPERT)
135
141
  is_agent_mode = (mode == MODE_AGENT)
136
142
  count_experts = self.window.core.experts.count_experts if is_agent_mode else None
137
143
  startswith_current = "current."
138
144
 
139
- index_fn = model.index
140
- set_item_data = model.setItemData
141
- display_role = QtCore.Qt.DisplayRole
142
- tooltip_role = QtCore.Qt.ToolTipRole
145
+ role_uuid = QtCore.Qt.UserRole + 1
146
+ role_id = QtCore.Qt.UserRole + 2
147
+ role_is_special = QtCore.Qt.UserRole + 3
143
148
 
144
149
  for i, (key, item) in enumerate(data.items()):
150
+ qitem = QStandardItem()
151
+
145
152
  name = item.name
146
153
  if is_expert_mode and item.enabled and not key.startswith(startswith_current):
147
154
  name = f"[x] {name}"
@@ -153,9 +160,38 @@ class Presets:
153
160
  prompt = str(item.prompt)
154
161
  tooltip = prompt if len(prompt) <= 80 else f"{prompt[:80]}..."
155
162
 
156
- idx = index_fn(i, 0)
157
- set_item_data(idx, {display_role: name, tooltip_role: tooltip})
163
+ qitem.setText(name)
164
+ qitem.setToolTip(tooltip)
165
+ qitem.setData(item.uuid, role_uuid)
166
+ qitem.setData(key, role_id)
167
+ qitem.setData(key.startswith(startswith_current), role_is_special)
168
+
169
+ # Pin row 0 (no drag, no drop)
170
+ # Other rows: drag enabled only; drop is handled by view between rows
171
+ if i != 0 and not key.startswith(startswith_current):
172
+ flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled
173
+ else:
174
+ flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
175
+ qitem.setFlags(flags)
176
+
177
+ model.appendRow(qitem)
158
178
  finally:
179
+ # Apply pending scroll (if any) before re-enabling updates
180
+ view.apply_pending_scroll()
159
181
  view.setUpdatesEnabled(True)
160
182
 
161
- view.restore_selection()
183
+ dnd_enabled = bool(self.window.core.config.get('presets.drag_and_drop.enabled'))
184
+ view.set_dnd_enabled(dnd_enabled)
185
+
186
+ # If override requested, force saved selection IDs to those override IDs
187
+ if selection_override_ids:
188
+ view._saved_selection_ids = list(selection_override_ids)
189
+ view._selection_override_ids = None # consume one-shot override
190
+
191
+ # Restore selection by ID (so it follows the same item even if rows moved)
192
+ view.restore_selection()
193
+ # Force repaint in case Qt defers layout until next input
194
+ view.viewport().update()
195
+
196
+ # Re-enable user interaction after the rebuild is fully done
197
+ view.end_model_update()
File without changes