pygpt-net 2.6.51__py3-none-any.whl → 2.6.53__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 (53) hide show
  1. pygpt_net/CHANGELOG.txt +10 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +3 -1
  4. pygpt_net/controller/__init__.py +4 -2
  5. pygpt_net/controller/audio/audio.py +22 -1
  6. pygpt_net/controller/chat/chat.py +5 -1
  7. pygpt_net/controller/chat/remote_tools.py +116 -0
  8. pygpt_net/controller/ctx/ctx.py +8 -3
  9. pygpt_net/controller/lang/mapping.py +2 -1
  10. pygpt_net/controller/mode/mode.py +5 -2
  11. pygpt_net/controller/plugins/plugins.py +29 -3
  12. pygpt_net/controller/realtime/realtime.py +8 -3
  13. pygpt_net/controller/ui/mode.py +11 -5
  14. pygpt_net/controller/ui/tabs.py +31 -7
  15. pygpt_net/core/ctx/output.py +4 -2
  16. pygpt_net/core/render/web/renderer.py +5 -4
  17. pygpt_net/core/tabs/tab.py +42 -9
  18. pygpt_net/core/tabs/tabs.py +7 -9
  19. pygpt_net/data/config/config.json +6 -5
  20. pygpt_net/data/config/models.json +3 -3
  21. pygpt_net/data/icons/web_off.svg +1 -0
  22. pygpt_net/data/icons/web_on.svg +1 -0
  23. pygpt_net/data/locale/locale.de.ini +1 -0
  24. pygpt_net/data/locale/locale.en.ini +3 -2
  25. pygpt_net/data/locale/locale.es.ini +1 -0
  26. pygpt_net/data/locale/locale.fr.ini +1 -0
  27. pygpt_net/data/locale/locale.it.ini +1 -0
  28. pygpt_net/data/locale/locale.pl.ini +1 -4
  29. pygpt_net/data/locale/locale.uk.ini +1 -0
  30. pygpt_net/data/locale/locale.zh.ini +1 -0
  31. pygpt_net/data/locale/plugin.mcp.en.ini +12 -0
  32. pygpt_net/icons.qrc +2 -0
  33. pygpt_net/icons_rc.py +232 -147
  34. pygpt_net/plugin/mcp/__init__.py +12 -0
  35. pygpt_net/plugin/mcp/config.py +103 -0
  36. pygpt_net/plugin/mcp/plugin.py +513 -0
  37. pygpt_net/plugin/mcp/worker.py +263 -0
  38. pygpt_net/provider/api/anthropic/tools.py +4 -2
  39. pygpt_net/provider/api/google/__init__.py +3 -2
  40. pygpt_net/provider/api/openai/agents/remote_tools.py +14 -4
  41. pygpt_net/provider/api/openai/chat.py +14 -2
  42. pygpt_net/provider/api/openai/remote_tools.py +5 -2
  43. pygpt_net/provider/api/x_ai/remote.py +6 -1
  44. pygpt_net/provider/core/config/patch.py +8 -1
  45. pygpt_net/ui/dialog/plugins.py +1 -3
  46. pygpt_net/ui/layout/chat/output.py +7 -2
  47. pygpt_net/ui/widget/element/labels.py +1 -2
  48. pygpt_net/ui/widget/tabs/body.py +24 -5
  49. {pygpt_net-2.6.51.dist-info → pygpt_net-2.6.53.dist-info}/METADATA +24 -4
  50. {pygpt_net-2.6.51.dist-info → pygpt_net-2.6.53.dist-info}/RECORD +53 -45
  51. {pygpt_net-2.6.51.dist-info → pygpt_net-2.6.53.dist-info}/LICENSE +0 -0
  52. {pygpt_net-2.6.51.dist-info → pygpt_net-2.6.53.dist-info}/WHEEL +0 -0
  53. {pygpt_net-2.6.51.dist-info → pygpt_net-2.6.53.dist-info}/entry_points.txt +0 -0
@@ -6,13 +6,15 @@
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.14 20:00:00 #
9
+ # Updated Date: 2025.09.16 22:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from datetime import datetime
13
13
  from typing import Dict, Any, Optional
14
14
  from dataclasses import dataclass, field
15
15
 
16
+ from PySide6.QtWidgets import QWidget
17
+
16
18
 
17
19
  @dataclass(slots=True)
18
20
  class Tab:
@@ -146,12 +148,37 @@ class Tab:
146
148
 
147
149
  :param widget: widget reference
148
150
  """
149
- for ref in self.refs:
150
- if ref and ref is widget:
151
- self.refs.remove(ref)
152
- break
153
- if self.child and hasattr(self.child, 'delete_ref'):
154
- self.child.delete_ref(widget)
151
+ try:
152
+ for ref in self.refs:
153
+ if ref and ref is widget:
154
+ self.refs.remove(ref)
155
+ break
156
+ except Exception:
157
+ pass
158
+
159
+ try:
160
+ if self.child and hasattr(self.child, 'delete_ref'):
161
+ self.child.delete_ref(widget)
162
+ except Exception:
163
+ pass
164
+
165
+ def unwrap(self, widget: QWidget):
166
+ """
167
+ Unwrap widget from this tab
168
+
169
+ :param widget: widget reference
170
+ """
171
+ self.delete_ref(widget)
172
+ try:
173
+ if widget and hasattr(widget, 'on_delete'):
174
+ widget.on_delete()
175
+ except Exception:
176
+ pass
177
+ try:
178
+ if self.child and hasattr(self.child, 'unwrap'):
179
+ self.child.unwrap(widget)
180
+ except Exception:
181
+ pass
155
182
 
156
183
  def to_dict(self) -> Dict[str, Any]:
157
184
  """
@@ -159,7 +186,7 @@ class Tab:
159
186
 
160
187
  :return: dict
161
188
  """
162
- return {
189
+ data = {
163
190
  "uuid": str(self.uuid),
164
191
  "pid": self.pid,
165
192
  "idx": self.idx,
@@ -169,7 +196,6 @@ class Tab:
169
196
  "icon": self.icon,
170
197
  "tooltip": self.tooltip,
171
198
  "data_id": self.data_id,
172
- "child": str(self.child), # child widget
173
199
  "parent": str(self.parent), # parent column
174
200
  "custom_name": self.custom_name,
175
201
  "custom_idx": self.new_idx,
@@ -179,6 +205,13 @@ class Tab:
179
205
  "tool_id": self.tool_id,
180
206
  "refs": [str(ref) for ref in self.refs], # references to widgets
181
207
  }
208
+ if self.child:
209
+ try:
210
+ if hasattr(self.child, 'to_dict'):
211
+ data['child'] = self.child.to_dict()
212
+ except Exception:
213
+ pass
214
+ return data
182
215
 
183
216
  def __str__(self) -> str:
184
217
  """
@@ -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.09.16 02:00:00 #
9
+ # Updated Date: 2025.09.16 22:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import uuid
@@ -299,20 +299,17 @@ class Tabs:
299
299
  if tab.type == Tab.TAB_CHAT:
300
300
  node = self.window.ui.nodes['output'].get(tab.pid)
301
301
  if node:
302
- node.unload() # unload web page
303
- tab.child.remove_widget(node)
302
+ node.unload() # unload page completely
303
+ tab.unwrap(node)
304
304
  self.window.ui.nodes['output'].pop(pid, None)
305
- node.on_delete()
306
305
  node_plain = self.window.ui.nodes['output_plain'].get(tab.pid)
307
306
  if node_plain:
308
- tab.child.remove_widget(node_plain)
307
+ tab.unwrap(node_plain)
309
308
  self.window.ui.nodes['output_plain'].pop(pid, None)
310
- node_plain.on_delete()
311
309
 
312
310
  if tab.type in (Tab.TAB_CHAT, Tab.TAB_NOTEPAD, Tab.TAB_TOOL):
313
- tab.cleanup() # unload assigned data from memory
314
-
315
- # tab.delete_refs()
311
+ tab.cleanup() # unload refs from memory
312
+ # IMPORTANT: leave refs to painter and calendar to keep only one instance of each
316
313
 
317
314
  except Exception as e:
318
315
  print(f"Error unloading tab {pid}: {e}")
@@ -328,6 +325,7 @@ class Tabs:
328
325
  """Remove all tabs"""
329
326
  for pid in list(self.pids.keys()):
330
327
  self.remove(pid) # delete from PIDs and UI
328
+ self.window.controller.chat.render.remove_pid(pid) # remove pid data from renderer registry
331
329
  self.pids = {}
332
330
  self.window.core.ctx.output.clear() # clear mapping
333
331
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.51",
4
- "app.version": "2.6.51",
5
- "updated_at": "2025-09-16T00:00:00"
3
+ "version": "2.6.53",
4
+ "app.version": "2.6.53",
5
+ "updated_at": "2025-09-17T00:00:00"
6
6
  },
7
7
  "access.audio.event.speech": false,
8
8
  "access.audio.event.speech.disabled": [],
@@ -417,6 +417,7 @@
417
417
  "remote_tools.computer_use.env": "",
418
418
  "remote_tools.file_search": false,
419
419
  "remote_tools.file_search.args": "",
420
+ "remote_tools.global.web_search": true,
420
421
  "remote_tools.google.code_interpreter": false,
421
422
  "remote_tools.google.url_ctx": false,
422
423
  "remote_tools.google.web_search": true,
@@ -434,8 +435,8 @@
434
435
  "render.code_syntax.final_max_chars": 350000,
435
436
  "render.code_syntax.final_max_lines": 1500,
436
437
  "render.code_syntax.stream_max_lines": 1000,
437
- "render.code_syntax.stream_n_line": 25,
438
- "render.code_syntax.stream_n_chars": 5000,
438
+ "render.code_syntax.stream_n_line": 10,
439
+ "render.code_syntax.stream_n_chars": 1000,
439
440
  "render.engine": "web",
440
441
  "render.memory.limit": "2.5GB",
441
442
  "render.msg.user.collapse.px": 1500,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.51",
4
- "app.version": "2.6.51",
5
- "updated_at": "2025-09-16T08:03:34"
3
+ "version": "2.6.53",
4
+ "app.version": "2.6.53",
5
+ "updated_at": "2025-09-17T08:03:34"
6
6
  },
7
7
  "items": {
8
8
  "SpeakLeash/bielik-11b-v2.3-instruct:Q4_K_M": {
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#686868"><path d="M819-28 701-146q-48 32-103.5 49T480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-62 17-117.5T146-701L27-820l57-57L876-85l-57 57ZM440-162v-78q-33 0-56.5-23.5T360-320v-40L168-552q-3 18-5.5 36t-2.5 36q0 121 79.5 212T440-162Zm374-99-58-58q21-37 32.5-77.5T800-480q0-98-54.5-179T600-776v16q0 33-23.5 56.5T520-680h-80v45L261-814q48-31 103-48.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 61-17.5 116T814-261Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#686868"><path d="M480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm-40-82v-78q-33 0-56.5-23.5T360-320v-40L168-552q-3 18-5.5 36t-2.5 36q0 121 79.5 212T440-162Zm276-102q41-45 62.5-100.5T800-480q0-98-54.5-179T600-776v16q0 33-23.5 56.5T520-680h-80v80q0 17-11.5 28.5T400-560h-80v80h240q17 0 28.5 11.5T600-440v120h40q26 0 47 15.5t29 40.5Z"/></svg>
@@ -677,6 +677,7 @@ html_canvas.btn.edit = Quellcode bearbeiten
677
677
  html_canvas.clear.confirm = HTML-Canvas-Ausgabe löschen?
678
678
  icon.audio.input = Audioeingang aktivieren/deaktivieren
679
679
  icon.audio.output = Audioausgang aktivieren/deaktivieren
680
+ icon.remote_tool.web = Websuche (ferngesteuertes Werkzeug, kein lokales Werkzeug)
680
681
  icon.video.capture = Videoaufnahme von der Kamera aktivieren/deaktivieren
681
682
  idx.btn.clear = Index löschen
682
683
  idx.btn.index_all = Alles indizieren
@@ -680,6 +680,7 @@ html_canvas.btn.edit = Edit source
680
680
  html_canvas.clear.confirm = Clear HTML canvas output?
681
681
  icon.audio.input = Enable/disable audio input
682
682
  icon.audio.output = Enable/disable audio output
683
+ icon.remote_tool.web = Web Search (remote tool, not a local tool)
683
684
  icon.video.capture = Enable/disable camera capture
684
685
  idx.btn.clear = Clear index
685
686
  idx.btn.index_all = Index all
@@ -1391,6 +1392,8 @@ settings.render.code_syntax.stream_n_line.desc = Syntax highlight: highlight eve
1391
1392
  settings.render.engine = Rendering engine
1392
1393
  settings.render.memory.limit = Memory Limit
1393
1394
  settings.render.memory.limit.desc = Renderer memory limit; set to 0 to disable. If > 0, the app will try to free memory after the limit is reached. Accepted formats: 3.5GB, 2GB, 2048MB, 1_000_000. Minimum: 2GB.
1395
+ settings.render.msg.user.collapse.px = Auto-collapse user message (px)
1396
+ settings.render.msg.user.collapse.px.desc = Auto-collapse user message after N pixels of height, set to 0 to disable auto-collapse
1394
1397
  settings.render.open_gl = OpenGL hardware acceleration
1395
1398
  settings.render.plain = Disable markdown formatting in output (RAW plain text mode)
1396
1399
  settings.render.web.only.desc = WebEngine / Chromium rendering engine only
@@ -1649,5 +1652,3 @@ vision.capture.manual.captured.success = Image captured from the camera:
1649
1652
  vision.capture.name.prefix = Camera capture:
1650
1653
  vision.capture.options.title = Video capture
1651
1654
  vision.checkbox.tooltip = If checked, the vision model is active. It will be automatically activated upon image upload. You can deactivate it in real-time.
1652
- settings.render.msg.user.collapse.px = Auto-collapse user message (px)
1653
- settings.render.msg.user.collapse.px.desc = Auto-collapse user message after N pixels of height, set to 0 to disable auto-collapse
@@ -678,6 +678,7 @@ html_canvas.btn.edit = Editar código fuente
678
678
  html_canvas.clear.confirm = ¿Limpiar la salida del lienzo HTML?
679
679
  icon.audio.input = Activar/desactivar entrada de audio
680
680
  icon.audio.output = Activar/desactivar salida de audio
681
+ icon.remote_tool.web = Búsqueda en la Web (herramienta remota, no una herramienta local)
681
682
  icon.video.capture = Activar/desactivar captura de vídeo desde la cámara
682
683
  idx.btn.clear = Limpiar índice
683
684
  idx.btn.index_all = Indexar todo
@@ -677,6 +677,7 @@ html_canvas.btn.edit = Modifier le code source
677
677
  html_canvas.clear.confirm = Effacer la sortie du canevas HTML ?
678
678
  icon.audio.input = Activer/désactiver l'entrée audio
679
679
  icon.audio.output = Activer/désactiver la sortie audio
680
+ icon.remote_tool.web = Recherche sur le Web (outil distant, pas un outil local)
680
681
  icon.video.capture = Activer/désactiver la capture vidéo depuis la caméra
681
682
  idx.btn.clear = Effacer l'index
682
683
  idx.btn.index_all = Indexer tout
@@ -677,6 +677,7 @@ html_canvas.btn.edit = Modifica il codice sorgente
677
677
  html_canvas.clear.confirm = Cancellare l'output del canvas HTML?
678
678
  icon.audio.input = Attiva/disattiva ingresso audio
679
679
  icon.audio.output = Attiva/disattiva uscita audio
680
+ icon.remote_tool.web = Ricerca Web (strumento remoto, non uno strumento locale)
680
681
  icon.video.capture = Attiva/disattiva cattura video dalla fotocamera
681
682
  idx.btn.clear = Cancella indice
682
683
  idx.btn.index_all = Indicizza tutto
@@ -1,8 +1,4 @@
1
1
  [LOCALE]
2
-
3
-
4
-
5
-
6
2
  about.btn.github = GitHub
7
3
  about.btn.support = Wsparcie
8
4
  about.btn.website = WWW
@@ -682,6 +678,7 @@ html_canvas.btn.edit = Edytuj kod źródłowy
682
678
  html_canvas.clear.confirm = Wyczyścić wynik płótna HTML?
683
679
  icon.audio.input = Włącz/wyłącz wejście audio
684
680
  icon.audio.output = Włącz/wyłącz wyjście audio
681
+ icon.remote_tool.web = Wyszukiwanie w sieci (narzędzie zdalne, nie lokalne)
685
682
  icon.video.capture = Włącz/wyłącz przechwytywanie wideo z kamery
686
683
  idx.btn.clear = Wyczyść indeks
687
684
  idx.btn.index_all = Indeksuj wszystko
@@ -677,6 +677,7 @@ html_canvas.btn.edit = Редагувати вихідний код
677
677
  html_canvas.clear.confirm = Очистити вихідні дані HTML-канви?
678
678
  icon.audio.input = Увімкнути/вимкнути аудіовхід
679
679
  icon.audio.output = Увімкнути/вимкнути аудіовихід
680
+ icon.remote_tool.web = Пошук у мережі (віддалений інструмент, не локальний інструмент)
680
681
  icon.video.capture = Увімкнути/вимкнути захоплення відео з камери
681
682
  idx.btn.clear = Очистити індекс
682
683
  idx.btn.index_all = Індексувати все
@@ -677,6 +677,7 @@ html_canvas.btn.edit = 编辑源代码
677
677
  html_canvas.clear.confirm = 清除HTML画布输出?
678
678
  icon.audio.input = 啟用/禁用音頻輸入
679
679
  icon.audio.output = 啟用/禁用音頻輸出
680
+ icon.remote_tool.web = 网页搜索(远程工具,非本地工具)
680
681
  icon.video.capture = 啟用/禁用相機捕捉
681
682
  idx.btn.clear = 清除索引
682
683
  idx.btn.index_all = 全部索引
@@ -0,0 +1,12 @@
1
+ [LOCALE]
2
+ plugin.description = Provides access to remote tools via the Model Context Protocol (MCP), including stdio, SSE, and Streamable HTTP transports, with per-server allow/deny filtering, Authorization header support, and a tools cache.
3
+ plugin.name = MCP
4
+ servers.description = Configure MCP servers. Supported transports: 'stdio: <command ...>' for stdio servers, 'http(s)://...' for Streamable HTTP, and 'http(s)://.../sse' (or 'sse://', 'sse+http(s)://') for SSE. Use 'label' as a short, human-friendly server name used in tool names. Use 'authorization' to send an Authorization header for HTTP/SSE connections. Use 'allowed_commands' (comma-separated) to whitelist tools; if provided, only those tools are exposed. Use 'disabled_commands' to blacklist tools from this server.
5
+ servers.label = MCP servers
6
+ servers.tooltip = Requires the MCP Python SDK. Install: pip install "mcp[cli]"
7
+ tools_cache_enabled.description = Enable an in-memory cache of discovered tools to avoid re-discovery on every prompt.
8
+ tools_cache_enabled.label = Cache tools list
9
+ tools_cache_enabled.tooltip = If enabled, tool discovery results are cached per server for the TTL duration.
10
+ tools_cache_ttl.description = Time-to-live for the tools cache per server.
11
+ tools_cache_ttl.label = Cache TTL (seconds)
12
+ tools_cache_ttl.tooltip = Set to 0 to disable TTL (not recommended).
pygpt_net/icons.qrc CHANGED
@@ -145,6 +145,8 @@
145
145
  <file alias="voice.svg">data/icons/voice.svg</file>
146
146
  <file alias="volume.svg">data/icons/volume.svg</file>
147
147
  <file alias="warning.svg">data/icons/warning.svg</file>
148
+ <file alias="web_off.svg">data/icons/web_off.svg</file>
149
+ <file alias="web_on.svg">data/icons/web_on.svg</file>
148
150
  <file alias="webcam.svg">data/icons/webcam.svg</file>
149
151
  <file alias="webcam_off.svg">data/icons/webcam_off.svg</file>
150
152
  <file alias="width.svg">data/icons/width.svg</file>