pygpt-net 2.6.38__py3-none-any.whl → 2.6.40__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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.38",
4
- "app.version": "2.6.38",
5
- "updated_at": "2025-09-05T00:00:00"
3
+ "version": "2.6.40",
4
+ "app.version": "2.6.40",
5
+ "updated_at": "2025-09-06T00:00:00"
6
6
  },
7
7
  "access.audio.event.speech": false,
8
8
  "access.audio.event.speech.disabled": [],
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.38",
4
- "app.version": "2.6.38",
5
- "updated_at": "2025-09-05T08:03:34"
3
+ "version": "2.6.40",
4
+ "app.version": "2.6.40",
5
+ "updated_at": "2025-09-06T08:03:34"
6
6
  },
7
7
  "items": {
8
8
  "SpeakLeash/bielik-11b-v2.3-instruct:Q4_K_M": {
@@ -181,7 +181,7 @@ code {{
181
181
  }}
182
182
  .msg-box .name-header.name-bot {{
183
183
  display: block;
184
- margin-left: -20px;
184
+ margin-left: -10px;
185
185
  margin-bottom: 1rem;
186
186
  color: #cfcfcf;
187
187
  }}
@@ -213,7 +213,7 @@ code {{
213
213
  }}
214
214
  .msg-box .name-header.name-bot {{
215
215
  display: block;
216
- margin-left: -20px;
216
+ margin-left: -10px;
217
217
  margin-bottom: 1rem;
218
218
  color: #cfcfcf;
219
219
  }}
@@ -210,7 +210,7 @@ code {{
210
210
  }}
211
211
  .msg-box .name-header.name-bot {{
212
212
  display: block;
213
- margin-left: -20px;
213
+ margin-left: -10px;
214
214
  margin-bottom: 1rem;
215
215
  color: #cfcfcf;
216
216
  }}
@@ -2475,6 +2475,15 @@ class Patch:
2475
2475
 
2476
2476
  updated = True
2477
2477
 
2478
+ # < 2.6.40
2479
+ if old < parse_version("2.6.40"):
2480
+ print("Migrating config from < 2.6.40...")
2481
+ # perf css
2482
+ patch_css('web-chatgpt.css', True)
2483
+ patch_css('web-chatgpt_wide.css', True)
2484
+ patch_css('web-blocks.css', True)
2485
+ updated = True
2486
+
2478
2487
  # update file
2479
2488
  migrated = False
2480
2489
  if updated:
@@ -10,6 +10,7 @@
10
10
  # ================================================== #
11
11
 
12
12
  import copy
13
+ from typing import Dict, List, Optional
13
14
 
14
15
  from PySide6.QtCore import Qt
15
16
  from PySide6.QtGui import QStandardItemModel, QIcon
@@ -27,8 +28,10 @@ from pygpt_net.ui.widget.option.dictionary import OptionDict
27
28
  from pygpt_net.ui.widget.option.input import OptionInput, PasswordInput
28
29
  from pygpt_net.ui.widget.option.slider import OptionSlider
29
30
  from pygpt_net.ui.widget.option.textarea import OptionTextarea
31
+ from pygpt_net.ui.widget.textarea.search_input import SearchInput
30
32
  from pygpt_net.utils import trans
31
33
 
34
+
32
35
  class Models:
33
36
  def __init__(self, window=None):
34
37
  """
@@ -39,6 +42,13 @@ class Models:
39
42
  self.window = window
40
43
  self.dialog_id = "models.editor"
41
44
 
45
+ # Internal state for filtering/mapping
46
+ self._filter_text: str = ""
47
+ self._filtered_ids: List[str] = [] # current list of model keys displayed in the view (order matters)
48
+ self._index_to_id: List[str] = [] # row index -> model key
49
+ self._id_to_index: Dict[str, int] = {} # model key -> row index
50
+ self._all_data: Dict[str, object] = {} # last known (unfiltered) data snapshot used to render the list
51
+
42
52
  def setup(self, idx=None):
43
53
  """
44
54
  Setup editor dialog
@@ -148,16 +158,29 @@ class Models:
148
158
  self.window.ui.nodes[id] = ModelEditorList(self.window, id)
149
159
  self.window.ui.models[id] = self.create_model(self.window)
150
160
  self.window.ui.nodes[id].setModel(self.window.ui.models[id])
151
-
152
- # update models list
161
+ self.window.ui.nodes[id].setMinimumWidth(250) # set max width to list
162
+
163
+ # search input (placed above the list)
164
+ self.window.ui.nodes['models.editor.search'] = SearchInput()
165
+ # Connect to provided callback API (callables assigned to attributes)
166
+ self.window.ui.nodes['models.editor.search'].on_search = self._on_search_models
167
+ self.window.ui.nodes['models.editor.search'].on_clear = self._on_clear_models # clear via "X" button
168
+
169
+ # container for search + list (left panel)
170
+ left_layout = QVBoxLayout()
171
+ left_layout.setContentsMargins(0, 0, 0, 0)
172
+ left_layout.setSpacing(6)
173
+ left_layout.addWidget(self.window.ui.nodes['models.editor.search'])
174
+ left_layout.addWidget(self.window.ui.nodes[id])
175
+ left_widget = QWidget()
176
+ left_widget.setLayout(left_layout)
177
+
178
+ # update models list (initial, unfiltered)
153
179
  self.update_list(id, data)
154
180
 
155
- # set max width to list
156
- self.window.ui.nodes[id].setMinimumWidth(250)
157
-
158
181
  # splitter
159
182
  self.window.ui.splitters['dialog.models'] = QSplitter(Qt.Horizontal)
160
- self.window.ui.splitters['dialog.models'].addWidget(self.window.ui.nodes[id]) # list
183
+ self.window.ui.splitters['dialog.models'].addWidget(left_widget) # search + list
161
184
  self.window.ui.splitters['dialog.models'].addWidget(area_widget) # tabs
162
185
  self.window.ui.splitters['dialog.models'].setStretchFactor(0, 2)
163
186
  self.window.ui.splitters['dialog.models'].setStretchFactor(1, 5)
@@ -184,6 +207,86 @@ class Models:
184
207
  if self.window.controller.model.editor.current is None:
185
208
  self.window.controller.model.editor.set_by_tab(0)
186
209
 
210
+ def _on_search_models(self, text: str):
211
+ """
212
+ Handle SearchInput callback. Filtering is prefix-based on model id or name (case-insensitive).
213
+ """
214
+ # Keep normalized filter text
215
+ self._filter_text = (text or "").strip().casefold()
216
+ # Re-apply list render using the last known dataset
217
+ self.update_list('models.list', self._all_data)
218
+ # Do not force-select rows here to avoid heavy editor re-initialization on each keystroke.
219
+
220
+ def _on_clear_models(self):
221
+ """
222
+ Handle SearchInput clear (click on 'X' button).
223
+ """
224
+ if not self._filter_text:
225
+ return
226
+ self._filter_text = ""
227
+ self.update_list('models.list', self._all_data)
228
+ # Try to restore selection for the current model if it is visible again.
229
+ self._restore_selection_for_current()
230
+
231
+ def _restore_selection_for_current(self):
232
+ """
233
+ Attempt to restore selection on the list to the current editor model if present in the view.
234
+ """
235
+ current_id = getattr(self.window.controller.model.editor, "current", None)
236
+ if not current_id:
237
+ return
238
+ idx = self.get_row_by_model_id(current_id)
239
+ if idx is None:
240
+ return
241
+ current = self.window.ui.models['models.list'].index(idx, 0)
242
+ self.window.ui.nodes['models.list'].setCurrentIndex(current)
243
+
244
+ def _apply_filter(self, data: Dict[str, object]) -> Dict[str, object]:
245
+ """
246
+ Return filtered data view, preserving original order.
247
+ """
248
+ if not self._filter_text:
249
+ return data
250
+
251
+ out: Dict[str, object] = {}
252
+ needle = self._filter_text
253
+ for mid, item in data.items():
254
+ # Normalize fields for prefix matching
255
+ model_id = (str(getattr(item, "id", mid)) or "").casefold()
256
+ model_name = (getattr(item, "name", "") or "").casefold()
257
+ if (needle in model_name
258
+ or needle in model_id):
259
+ out[mid] = item
260
+ return out
261
+
262
+ def _refresh_index_mapping(self, ids: List[str]):
263
+ """
264
+ Build fast row<->id mapping for the current filtered list.
265
+ """
266
+ self._filtered_ids = list(ids)
267
+ self._index_to_id = list(ids)
268
+ self._id_to_index = {mid: idx for idx, mid in enumerate(ids)}
269
+
270
+ def get_model_id_by_row(self, row: int) -> Optional[str]:
271
+ """
272
+ Map a view row index to the model id currently displayed at that row.
273
+ """
274
+ if 0 <= row < len(self._index_to_id):
275
+ return self._index_to_id[row]
276
+ return None
277
+
278
+ def get_row_by_model_id(self, model_id: str) -> Optional[int]:
279
+ """
280
+ Map a model id to its current row index in the filtered view.
281
+ """
282
+ return self._id_to_index.get(model_id)
283
+
284
+ def get_filtered_ids(self) -> List[str]:
285
+ """
286
+ Return a copy of currently visible model ids (filtered order).
287
+ """
288
+ return list(self._filtered_ids)
289
+
187
290
  def build_widgets(self, options: dict) -> dict:
188
291
  """
189
292
  Build settings options widgets
@@ -333,6 +436,21 @@ class Models:
333
436
  """
334
437
  return QStandardItemModel(0, 1, parent)
335
438
 
439
+ def _get_provider_display_name(self, provider_id: str) -> str:
440
+ """
441
+ Resolve provider display name using app's LLM provider registry.
442
+ """
443
+ if not provider_id:
444
+ return ""
445
+ try:
446
+ name = self.window.core.llm.get_provider_name(provider_id)
447
+ if isinstance(name, str):
448
+ name = name.strip()
449
+ return name or ""
450
+ except Exception:
451
+ # Fail silently to avoid breaking the models list rendering
452
+ return ""
453
+
336
454
  def update_list(self, id: str, data: dict):
337
455
  """
338
456
  Update list
@@ -340,10 +458,40 @@ class Models:
340
458
  :param id: ID of the list
341
459
  :param data: Data to update
342
460
  """
461
+ # Keep latest source data for subsequent filtering cycles
462
+ self._all_data = dict(data)
463
+
464
+ # Apply current filter (preserve insertion/sorted order)
465
+ filtered = self._apply_filter(self._all_data)
466
+
467
+ # Reset model rows
343
468
  self.window.ui.models[id].removeRows(0, self.window.ui.models[id].rowCount())
469
+
470
+ # Count occurrences of each model display name to detect duplicates (in filtered view)
471
+ name_counts = {}
472
+ for key in filtered:
473
+ item = filtered[key]
474
+ base_name = getattr(item, "name", "") or ""
475
+ name_counts[base_name] = name_counts.get(base_name, 0) + 1
476
+
477
+ # Populate rows with optional provider suffix for duplicate names
344
478
  i = 0
345
- for n in data:
479
+ row_ids: List[str] = []
480
+ for n in filtered:
481
+ item = filtered[n]
482
+ base_name = getattr(item, "name", "") or ""
483
+ display_name = base_name
484
+ if name_counts.get(base_name, 0) > 1:
485
+ provider_id = getattr(item, "provider", None)
486
+ provider_name = self._get_provider_display_name(provider_id) if provider_id else ""
487
+ if provider_name:
488
+ display_name = f"{base_name} ({provider_name})"
489
+
346
490
  self.window.ui.models[id].insertRow(i)
347
- name = data[n].name
348
- self.window.ui.models[id].setData(self.window.ui.models[id].index(i, 0), name)
491
+ self.window.ui.models[id].setData(self.window.ui.models[id].index(i, 0), display_name)
492
+ # IMPORTANT: map list row to the dictionary key (stable and unique within models.items)
493
+ row_ids.append(n)
349
494
  i += 1
495
+
496
+ # Refresh index mappings used by Editor
497
+ self._refresh_index_mapping(row_ids)
pygpt_net/utils.py CHANGED
@@ -269,28 +269,25 @@ def natsort(l: list) -> list:
269
269
  return sorted(l, key=alphanum_key)
270
270
 
271
271
  def mem_clean():
272
- """
273
- Clean memory by removing unused variables
274
- """
275
- return # temporary disabled
276
-
272
+ """Clean memory by removing unused objects"""
273
+ return
277
274
  import sys, gc
278
275
  ok = False
279
276
  try:
280
277
  gc.collect()
281
- except Exception:
282
- pass
278
+ except Exception as e:
279
+ print(e)
283
280
 
284
281
  try:
285
282
  QApplication.sendPostedEvents(None, QtCore.QEvent.DeferredDelete)
286
283
  QApplication.processEvents(QtCore.QEventLoop.AllEvents, 50)
287
- except Exception:
288
- pass
284
+ except Exception as e:
285
+ print(e)
289
286
 
290
287
  try:
291
288
  QtGui.QPixmapCache.clear()
292
- except Exception:
293
- pass
289
+ except Exception as e:
290
+ print(e)
294
291
 
295
292
  try:
296
293
  if sys.platform.startswith("linux"):
@@ -299,6 +296,7 @@ def mem_clean():
299
296
  if hasattr(libc, "malloc_trim"):
300
297
  libc.malloc_trim(0)
301
298
  ok = True
299
+ '''
302
300
  elif sys.platform == "win32":
303
301
  import ctypes, ctypes.wintypes
304
302
  kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
@@ -322,6 +320,7 @@ def mem_clean():
322
320
  ok = True
323
321
  except Exception:
324
322
  pass
325
- except Exception:
326
- pass
323
+ '''
324
+ except Exception as e:
325
+ print(e)
327
326
  return ok
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pygpt-net
3
- Version: 2.6.38
3
+ Version: 2.6.40
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, 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
@@ -118,7 +118,7 @@ Description-Content-Type: text/markdown
118
118
 
119
119
  [![pygpt](https://snapcraft.io/pygpt/badge.svg)](https://snapcraft.io/pygpt)
120
120
 
121
- Release: **2.6.38** | build: **2025-09-05** | Python: **>=3.10, <3.14**
121
+ Release: **2.6.40** | build: **2025-09-06** | Python: **>=3.10, <3.14**
122
122
 
123
123
  > Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
124
124
  >
@@ -3565,6 +3565,15 @@ may consume additional tokens that are not displayed in the main window.
3565
3565
 
3566
3566
  ## Recent changes:
3567
3567
 
3568
+ **2.6.40 (2025-09-06)**
3569
+
3570
+ - CSS fixes.
3571
+
3572
+ **2.6.39 (2025-09-06)**
3573
+
3574
+ - Added: Search input to the models editor.
3575
+ - Fixed: Brush color switching when changing modes in the Painter.
3576
+
3568
3577
  **2.6.38 (2025-09-05)**
3569
3578
 
3570
3579
  - Fixed: Detection of chunk type in Ollama.
@@ -1,6 +1,6 @@
1
- pygpt_net/CHANGELOG.txt,sha256=g_mDeVYrI59mmY_VZW1AHnEs4OgnRwdUnUOcUKg-Ec8,104767
1
+ pygpt_net/CHANGELOG.txt,sha256=n9-GJ5lBCR84tUm6y7L-w5ph8Wwj9eZkApNZV7nZcog,104935
2
2
  pygpt_net/LICENSE,sha256=dz9sfFgYahvu2NZbx4C1xCsVn9GVer2wXcMkFRBvqzY,1146
3
- pygpt_net/__init__.py,sha256=BqCXpFHlJqSkrmApXJqlpuUhwsRixNBHj1AnuY9wbeo,1373
3
+ pygpt_net/__init__.py,sha256=zLYjQ-y3zB7Or2LawHwhWh4dtz2KtytVxU3ACx0Bmvs,1373
4
4
  pygpt_net/app.py,sha256=26N6af9L88rTeYmYIgP9amoPJB-o3Sc5_MFHLNckbWk,21817
5
5
  pygpt_net/app_core.py,sha256=y7mHzH_sdUg2yoG_BKvMdJA6v5jCBSHhwcXqIZfxXs4,4169
6
6
  pygpt_net/config.py,sha256=SCps_FfwdrynVAgpn37Ci1qTN8BFC05IGl9sYIi9e0w,16720
@@ -110,14 +110,14 @@ pygpt_net/controller/media/media.py,sha256=Fox4li3HRGL0wI9yJ6WyaiFSBm5znuumET7ro
110
110
  pygpt_net/controller/mode/__init__.py,sha256=1Kcz0xHc2IW_if9S9eQozBUvIu69eLAe7T-Re2lJxhk,508
111
111
  pygpt_net/controller/mode/mode.py,sha256=WdaNA7-n6mTkkRkKIMUltxBC_vRAwWzkUEt9rOpIRBM,7840
112
112
  pygpt_net/controller/model/__init__.py,sha256=mQXq9u269D8TD3u_44J6DFFyHKkaZplk-tRFCssBGbE,509
113
- pygpt_net/controller/model/editor.py,sha256=3DywV3VL80CSpxFCADCWmULuXdV7ILvdkAqty17zsaA,16536
113
+ pygpt_net/controller/model/editor.py,sha256=tHJ2eT_OdmKygKG7Xe3IKpXdxApafPxL2rje4crn3gs,16108
114
114
  pygpt_net/controller/model/importer.py,sha256=9O35I0DjFOudWS41n5WPsKYFQm_K0XHOUKXvJt7l5kI,23837
115
115
  pygpt_net/controller/model/model.py,sha256=E0VfgIwNn75pjnB_v3RnqHr6jV1Eeua8VgpreQlA8vI,9132
116
116
  pygpt_net/controller/notepad/__init__.py,sha256=ZbMh4D6nsGuI4AwYMdegfij5ubmUznEE_UcqSSDjSPk,511
117
117
  pygpt_net/controller/notepad/notepad.py,sha256=Mn3XOrNq8_7EHq3Jf9fMyJ6YzHRawczRXfoZbn2f7L4,11155
118
118
  pygpt_net/controller/painter/__init__.py,sha256=ZNZE6YcKprDPqLK5kiwtcJVvcW3H-YkerFW0PwbeQ1Y,511
119
119
  pygpt_net/controller/painter/capture.py,sha256=X3TqnNypxT_wngkQ4ovfS9glQwoGHyM-peR5aLJQGvk,6666
120
- pygpt_net/controller/painter/common.py,sha256=SArFGHN_lwt82iJoHr8keHt4WLEM6uv9gKPURlluyVo,15920
120
+ pygpt_net/controller/painter/common.py,sha256=O_AQKhM7iHb6aqzqMW0a9KH66MX8tho3HOJUpfLx39Y,15411
121
121
  pygpt_net/controller/painter/painter.py,sha256=_M3iqeFPoFwtQJzwcpIVvMRT2YZa819-0wvfd6nvj2Y,2847
122
122
  pygpt_net/controller/plugins/__init__.py,sha256=iocY37De1H2Nh7HkC7ZYvUus2xzcckslgr5a4PwtQII,511
123
123
  pygpt_net/controller/plugins/plugins.py,sha256=ULxjobGy5oJY9UTjx75jsFj49zTlnOD2llEyQSH275A,15269
@@ -345,7 +345,7 @@ pygpt_net/core/render/plain/helpers.py,sha256=tWbdJZBfjnuHLAUDVYLTfv3Vt-h7XN1tg6
345
345
  pygpt_net/core/render/plain/pid.py,sha256=Zp-TNjKI3yReuSJxC8qRkOh2ou7zK6abFbXjebbpsO8,1484
346
346
  pygpt_net/core/render/plain/renderer.py,sha256=mb1d6UBbuOs_fotG9fZPdBk95i8n0UMCJNnF4an8E0o,15357
347
347
  pygpt_net/core/render/web/__init__.py,sha256=istp5dsn6EkLEP7lOBeDb8RjodUcWZqjcEvTroaTT-w,489
348
- pygpt_net/core/render/web/body.py,sha256=rMbIHJAcEayKkwIrjdxF85MFS0wUQGGmsylskZy7cQM,77100
348
+ pygpt_net/core/render/web/body.py,sha256=JckJ7BCDdcmCRPXi6K-a6svbp2bi9HGbd2QCXBgjLiQ,72388
349
349
  pygpt_net/core/render/web/helpers.py,sha256=KAmUNUuIk8gArCMkyWcK_Ak0uxJOuIULt5eOA-jnjJM,5757
350
350
  pygpt_net/core/render/web/parser.py,sha256=pDFc9Tf8P-jvrDilXyT1fukcQHbixHRJ9Dn9hF10Gko,12892
351
351
  pygpt_net/core/render/web/pid.py,sha256=nCbwS5MOyfp8vn4pME6JYgRtnd-4U74FEntXYJM6GqY,4180
@@ -390,8 +390,8 @@ pygpt_net/css_rc.py,sha256=i13kX7irhbYCWZ5yJbcMmnkFp_UfS4PYnvRFSPF7XXo,11349
390
390
  pygpt_net/data/audio/click_off.mp3,sha256=aNiRDP1pt-Jy7ija4YKCNFBwvGWbzU460F4pZWZDS90,65201
391
391
  pygpt_net/data/audio/click_on.mp3,sha256=qfdsSnthAEHVXzeyN4LlC0OvXuyW8p7stb7VXtlvZ1k,65201
392
392
  pygpt_net/data/audio/ok.mp3,sha256=LTiV32pEBkpUGBkKkcOdOFB7Eyt_QoP2Nv6c5AaXftk,32256
393
- pygpt_net/data/config/config.json,sha256=SAtwXnEXfPeVcWJypiQGsT0mm1E2lUadd-Ofzm8VT7U,30498
394
- pygpt_net/data/config/models.json,sha256=p19-g9BJChckxiQiSofy-pkkM5E6MTq7e84q5wONzFM,115730
393
+ pygpt_net/data/config/config.json,sha256=kkQ6a1La_1ctA5vDAX9Yy3zXYutXCq_tfKCULxGXTto,30498
394
+ pygpt_net/data/config/models.json,sha256=M6SaFXHtiBmqBAfhQiAM_MweIcojL9rH7YY22f2ymIA,115730
395
395
  pygpt_net/data/config/modes.json,sha256=IpjLOm428_vs6Ma9U-YQTNKJNtZw-qyM1lwhh73xl1w,2111
396
396
  pygpt_net/data/config/presets/agent_code_act.json,sha256=GYHqhxtKFLUCvRI3IJAJ7Qe1k8yD9wGGNwManldWzlI,754
397
397
  pygpt_net/data/config/presets/agent_openai.json,sha256=bpDJgLRey_effQkzFRoOEGd4aHUrmzeODSDdNzrf62I,730
@@ -437,15 +437,15 @@ pygpt_net/data/css/markdown.light.css,sha256=UZdv0jtuFgJ_4bYWsDaDQ4X4AP9tVNLUHBA
437
437
  pygpt_net/data/css/style.css,sha256=dgVlVqEL38zF-4Ok-y1rwfALC8zETJAIuIbkwat_hTk,337
438
438
  pygpt_net/data/css/style.dark.css,sha256=J1-QK93ZY2X0nJmuZSZThy9mSuW3mJtk2x4gO9sq-ms,2332
439
439
  pygpt_net/data/css/style.light.css,sha256=qJumh5HSwzGiDPoYKcKz_-8cOvV8D9QM74PtxnHBOqE,4914
440
- pygpt_net/data/css/web-blocks.css,sha256=3JnSMKzMHt6_ZXw6HteEDvxfmvtyk6SCr_G7B6Ralr4,7417
440
+ pygpt_net/data/css/web-blocks.css,sha256=-vJ1ugPpG2DTtoPxg_4iTMORKaDvDJOK9Yu5D7xe1XE,7417
441
441
  pygpt_net/data/css/web-blocks.dark.css,sha256=eU8-uXcvu4weRp55CZmhB-6nK7P6n9m-OyJwGV95rJc,1514
442
442
  pygpt_net/data/css/web-blocks.darkest.css,sha256=kRv3qqTbjZxEITtQUm3RmrkGoZosMZjs423lUyTFyAQ,1466
443
443
  pygpt_net/data/css/web-blocks.light.css,sha256=bmJyOCi6qytbxLmBrO4hVU99y0ymOo9kof3EGLEZRLg,1541
444
- pygpt_net/data/css/web-chatgpt.css,sha256=Ox4yE93BnhrqrCHcf4wdJkR_gSJDxUThn0YQ2clYGGM,7985
444
+ pygpt_net/data/css/web-chatgpt.css,sha256=MY5DNUMa6_q4BV7_cCg99zh3hoMpE1yVm_Wr_ALiSxE,7985
445
445
  pygpt_net/data/css/web-chatgpt.dark.css,sha256=8INjPiZGndfie_QdJTHhEgT7k4dmT0aph6WYmU79Yy4,1435
446
446
  pygpt_net/data/css/web-chatgpt.darkest.css,sha256=X2myPkIMYa77RUZ7jucxbyWIomRyqYAg_wqmZA1E0mM,1387
447
447
  pygpt_net/data/css/web-chatgpt.light.css,sha256=AvCdgVqUFwU9zyrQJxJkzq09NCDwSKI-FskTKoW-rNI,1536
448
- pygpt_net/data/css/web-chatgpt_wide.css,sha256=QYR1AYi1Cu9ESQAa-p4yJ0xO6M2v9vtPtBS6A4kpUcc,7891
448
+ pygpt_net/data/css/web-chatgpt_wide.css,sha256=5_pMsduh3lLLO6MJ_g9iiIicAMjHnPau5t3xN08OPgA,7891
449
449
  pygpt_net/data/css/web-chatgpt_wide.dark.css,sha256=8INjPiZGndfie_QdJTHhEgT7k4dmT0aph6WYmU79Yy4,1435
450
450
  pygpt_net/data/css/web-chatgpt_wide.darkest.css,sha256=X2myPkIMYa77RUZ7jucxbyWIomRyqYAg_wqmZA1E0mM,1387
451
451
  pygpt_net/data/css/web-chatgpt_wide.light.css,sha256=WWhVX4xbDOPgW7O2SIRZCvWR1N8fzqviFO5fhe-AvDs,1503
@@ -2148,7 +2148,7 @@ pygpt_net/provider/core/calendar/db_sqlite/storage.py,sha256=QDclQCQdr4QyRIqjgGX
2148
2148
  pygpt_net/provider/core/config/__init__.py,sha256=jQQgG9u_ZLsZWXustoc1uvC-abUvj4RBKPAM30-f2Kc,488
2149
2149
  pygpt_net/provider/core/config/base.py,sha256=cbvzbMNqL2XgC-36gGubnU37t94AX7LEw0lecb2Nm80,1365
2150
2150
  pygpt_net/provider/core/config/json_file.py,sha256=GCcpCRQnBiSLWwlGbG9T3ZgiHkTfp5Jsg2KYkZcakBw,6789
2151
- pygpt_net/provider/core/config/patch.py,sha256=F8r0qk4yWxCtkR8abKDeXucqoerG_w08GO4mXIPrpNg,126027
2151
+ pygpt_net/provider/core/config/patch.py,sha256=QI-eu4i5rOt_9FeGzflL2cTO889rwOKA9fDfzyTsnDg,126371
2152
2152
  pygpt_net/provider/core/ctx/__init__.py,sha256=jQQgG9u_ZLsZWXustoc1uvC-abUvj4RBKPAM30-f2Kc,488
2153
2153
  pygpt_net/provider/core/ctx/base.py,sha256=Tfb4MDNe9BXXPU3lbzpdYwJF9S1oa2-mzgu5XT4It9g,3003
2154
2154
  pygpt_net/provider/core/ctx/db_sqlite/__init__.py,sha256=0dP8VhI4bnFsQQKxAkaleKFlyaMycDD_cnE7gBCa57Y,512
@@ -2363,7 +2363,7 @@ pygpt_net/ui/dialog/find.py,sha256=8VAcSRFkCLu4Yum6LwHgHg_8Ogn_ytco0ShaJLIJDXk,9
2363
2363
  pygpt_net/ui/dialog/image.py,sha256=nF7ejD44_UAAppUC3OpqaoSvzA-NM2B5fVOO0L8vFBE,2538
2364
2364
  pygpt_net/ui/dialog/license.py,sha256=15Qrk_vnybnI3CAtvOHYJy8cSAkIG7fPG-HYqmSdctQ,2272
2365
2365
  pygpt_net/ui/dialog/logger.py,sha256=OGFKlAyeMgNQI4a-VW9bDXSrcsPtEC6rLhtdu11lsJc,2296
2366
- pygpt_net/ui/dialog/models.py,sha256=3t1z5j7zSw_y2fIL0iwLNYzMjBu6v-IbD1cMazla-Tk,13532
2366
+ pygpt_net/ui/dialog/models.py,sha256=WnVvv1pFwTTXmK3uM9bNX59GMccDGxvKhAYxJXW88fs,19717
2367
2367
  pygpt_net/ui/dialog/models_importer.py,sha256=14kxf7KkOdTP-tcgTN5OphNZajlivDPTDKBosebuyog,4505
2368
2368
  pygpt_net/ui/dialog/plugins.py,sha256=gi7tWH0Il3akehiOO3EcwoUt55vq7ANCwrd3YDSnHCw,20419
2369
2369
  pygpt_net/ui/dialog/preset.py,sha256=G-nGxu0OUCrFUFLpT8XCJL9rWBCG6eEKNciQbLBB39s,17196
@@ -2537,9 +2537,9 @@ pygpt_net/ui/widget/textarea/url.py,sha256=xbNQxoM5fYI1ZWbvybQkPmNPrIq3yhtNPBOSO
2537
2537
  pygpt_net/ui/widget/textarea/web.py,sha256=0t49MoTK_ZcGeYvIeiIvCKbRXvzQLO2Ko8INIP1pOcY,19904
2538
2538
  pygpt_net/ui/widget/vision/__init__.py,sha256=8HT4tQFqQogEEpGYTv2RplKBthlsFKcl5egnv4lzzEw,488
2539
2539
  pygpt_net/ui/widget/vision/camera.py,sha256=v1qEncaZr5pXocO5Cpk_lsgfCMvfFigdJmzsYfzvCl0,1877
2540
- pygpt_net/utils.py,sha256=o3V8NLcTQm8XkP6n_M88jVbI7OjnryRmsvnvf7K136A,9100
2541
- pygpt_net-2.6.38.dist-info/LICENSE,sha256=rbPqNB_xxANH8hKayJyIcTwD4bj4Y2G-Mcm85r1OImM,1126
2542
- pygpt_net-2.6.38.dist-info/METADATA,sha256=TyuaDMfHUf7MJ9vyXE18msfBnmwS66oWqXH4UQDj2ac,163286
2543
- pygpt_net-2.6.38.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
2544
- pygpt_net-2.6.38.dist-info/entry_points.txt,sha256=qvpII6UHIt8XfokmQWnCYQrTgty8FeJ9hJvOuUFCN-8,43
2545
- pygpt_net-2.6.38.dist-info/RECORD,,
2540
+ pygpt_net/utils.py,sha256=XtfRfEPuoQ4OCO19o1UqkP1BmpGvPZ6kvHo33Xqcdr0,9125
2541
+ pygpt_net-2.6.40.dist-info/LICENSE,sha256=rbPqNB_xxANH8hKayJyIcTwD4bj4Y2G-Mcm85r1OImM,1126
2542
+ pygpt_net-2.6.40.dist-info/METADATA,sha256=HV6AFqSRvBpom_XFjNwmGrkknRtIvpvT45XamJe0KZs,163462
2543
+ pygpt_net-2.6.40.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
2544
+ pygpt_net-2.6.40.dist-info/entry_points.txt,sha256=qvpII6UHIt8XfokmQWnCYQrTgty8FeJ9hJvOuUFCN-8,43
2545
+ pygpt_net-2.6.40.dist-info/RECORD,,