pygpt-net 2.6.3__py3-none-any.whl → 2.6.4__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 (66) hide show
  1. pygpt_net/CHANGELOG.txt +5 -0
  2. pygpt_net/__init__.py +1 -1
  3. pygpt_net/config.py +55 -65
  4. pygpt_net/controller/chat/chat.py +38 -35
  5. pygpt_net/controller/chat/render.py +144 -217
  6. pygpt_net/controller/chat/stream.py +51 -25
  7. pygpt_net/controller/config/config.py +39 -42
  8. pygpt_net/controller/config/field/checkbox.py +16 -12
  9. pygpt_net/controller/config/field/checkbox_list.py +36 -31
  10. pygpt_net/controller/config/field/cmd.py +51 -57
  11. pygpt_net/controller/config/field/combo.py +33 -16
  12. pygpt_net/controller/config/field/dictionary.py +48 -55
  13. pygpt_net/controller/config/field/input.py +50 -32
  14. pygpt_net/controller/config/field/slider.py +40 -45
  15. pygpt_net/controller/config/field/textarea.py +20 -6
  16. pygpt_net/controller/config/placeholder.py +110 -231
  17. pygpt_net/controller/lang/mapping.py +57 -95
  18. pygpt_net/controller/lang/plugins.py +64 -55
  19. pygpt_net/controller/lang/settings.py +39 -38
  20. pygpt_net/controller/layout/layout.py +11 -2
  21. pygpt_net/controller/plugins/plugins.py +19 -1
  22. pygpt_net/controller/ui/mode.py +107 -125
  23. pygpt_net/core/bridge/bridge.py +5 -5
  24. pygpt_net/core/command/command.py +149 -219
  25. pygpt_net/core/ctx/ctx.py +94 -146
  26. pygpt_net/core/debug/debug.py +48 -58
  27. pygpt_net/core/models/models.py +74 -112
  28. pygpt_net/core/modes/modes.py +13 -21
  29. pygpt_net/core/plugins/plugins.py +154 -177
  30. pygpt_net/core/presets/presets.py +103 -176
  31. pygpt_net/core/render/web/body.py +2 -3
  32. pygpt_net/core/render/web/renderer.py +109 -180
  33. pygpt_net/core/text/utils.py +28 -44
  34. pygpt_net/core/tokens/tokens.py +104 -203
  35. pygpt_net/data/config/config.json +2 -2
  36. pygpt_net/data/config/models.json +2 -2
  37. pygpt_net/item/ctx.py +141 -139
  38. pygpt_net/plugin/agent/plugin.py +2 -1
  39. pygpt_net/plugin/audio_output/plugin.py +5 -2
  40. pygpt_net/plugin/base/plugin.py +77 -93
  41. pygpt_net/plugin/bitbucket/plugin.py +3 -2
  42. pygpt_net/plugin/cmd_code_interpreter/plugin.py +3 -2
  43. pygpt_net/plugin/cmd_custom/plugin.py +3 -2
  44. pygpt_net/plugin/cmd_files/plugin.py +3 -2
  45. pygpt_net/plugin/cmd_history/plugin.py +3 -2
  46. pygpt_net/plugin/cmd_mouse_control/plugin.py +5 -2
  47. pygpt_net/plugin/cmd_serial/plugin.py +3 -2
  48. pygpt_net/plugin/cmd_system/plugin.py +3 -6
  49. pygpt_net/plugin/cmd_web/plugin.py +3 -2
  50. pygpt_net/plugin/experts/plugin.py +2 -2
  51. pygpt_net/plugin/facebook/plugin.py +3 -4
  52. pygpt_net/plugin/github/plugin.py +4 -2
  53. pygpt_net/plugin/google/plugin.py +3 -3
  54. pygpt_net/plugin/idx_llama_index/plugin.py +3 -2
  55. pygpt_net/plugin/mailer/plugin.py +3 -5
  56. pygpt_net/plugin/openai_vision/plugin.py +3 -2
  57. pygpt_net/plugin/real_time/plugin.py +52 -60
  58. pygpt_net/plugin/slack/plugin.py +3 -4
  59. pygpt_net/plugin/telegram/plugin.py +3 -4
  60. pygpt_net/plugin/twitter/plugin.py +3 -4
  61. pygpt_net/ui/widget/textarea/web.py +18 -14
  62. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.4.dist-info}/METADATA +7 -2
  63. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.4.dist-info}/RECORD +66 -66
  64. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.4.dist-info}/LICENSE +0 -0
  65. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.4.dist-info}/WHEEL +0 -0
  66. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.4.dist-info}/entry_points.txt +0 -0
@@ -6,17 +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.07.14 00:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
- import os
13
12
 
14
13
  from pygpt_net.plugin.base.plugin import BasePlugin
15
14
  from pygpt_net.core.events import Event
16
15
  from pygpt_net.item.ctx import CtxItem
17
16
 
18
17
  from .config import Config
19
- from .worker import Worker
20
18
 
21
19
 
22
20
  class Plugin(BasePlugin):
@@ -98,6 +96,8 @@ class Plugin(BasePlugin):
98
96
  :param ctx: CtxItem
99
97
  :param cmds: commands dict
100
98
  """
99
+ from .worker import Worker
100
+
101
101
  is_cmd = False
102
102
  my_commands = []
103
103
  for item in cmds:
@@ -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.06.30 02:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import json
@@ -21,7 +21,6 @@ from pygpt_net.item.ctx import CtxItem
21
21
  from pygpt_net.core.bridge.context import BridgeContext
22
22
 
23
23
  from .config import Config
24
- from .worker import Worker
25
24
 
26
25
  class Plugin(BasePlugin):
27
26
  def __init__(self, *args, **kwargs):
@@ -318,6 +317,8 @@ class Plugin(BasePlugin):
318
317
  :param ctx: CtxItem
319
318
  :param cmds: commands dict
320
319
  """
320
+ from .worker import Worker
321
+
321
322
  is_cmd = False
322
323
  my_commands = []
323
324
  for item in cmds:
@@ -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: 2024.12.15 04:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.plugin.base.plugin import BasePlugin
@@ -15,10 +15,6 @@ from pygpt_net.item.ctx import CtxItem
15
15
 
16
16
  from .config import Config
17
17
  from .runner import Runner
18
- from .worker import Worker
19
-
20
- from pygpt_net.utils import trans
21
-
22
18
 
23
19
  class Plugin(BasePlugin):
24
20
  def __init__(self, *args, **kwargs):
@@ -88,6 +84,8 @@ class Plugin(BasePlugin):
88
84
  :param cmds: commands dict
89
85
  :param silent: silent mode
90
86
  """
87
+ from .worker import Worker
88
+
91
89
  is_cmd = False
92
90
  force = False
93
91
  my_commands = []
@@ -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.07.30 00:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.core.types import (
@@ -25,7 +25,6 @@ from pygpt_net.item.ctx import CtxItem
25
25
  from pygpt_net.core.events import Event
26
26
 
27
27
  from .config import Config
28
- from .worker import Worker
29
28
 
30
29
  class Plugin(BasePlugin):
31
30
  def __init__(self, *args, **kwargs):
@@ -199,6 +198,8 @@ class Plugin(BasePlugin):
199
198
  :param ctx: CtxItem
200
199
  :param cmds: commands dict
201
200
  """
201
+ from .worker import Worker
202
+
202
203
  is_cmd = False
203
204
  needed_lock = False
204
205
  my_commands = []
@@ -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: 2024.11.29 23:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from datetime import datetime
@@ -51,31 +51,18 @@ class Plugin(BasePlugin):
51
51
  ctx = event.ctx
52
52
 
53
53
  if name == Event.POST_PROMPT_END:
54
- silent = False
55
- if 'silent' in data and data['silent']:
56
- silent = True
57
- data['value'] = self.on_system_prompt(
58
- data['value'],
59
- silent,
60
- )
61
-
62
- if name == Event.AGENT_PROMPT:
63
- silent = False
64
- if 'silent' in data and data['silent']:
65
- silent = True
66
- data['value'] = self.on_agent_prompt(
67
- data['value'],
68
- silent,
69
- )
54
+ silent = bool(data.get('silent'))
55
+ data['value'] = self.on_system_prompt(data['value'], silent)
56
+
57
+ elif name == Event.AGENT_PROMPT:
58
+ silent = bool(data.get('silent'))
59
+ data['value'] = self.on_agent_prompt(data['value'], silent)
70
60
 
71
61
  elif name == Event.CMD_SYNTAX:
72
62
  self.cmd_syntax(data)
73
63
 
74
64
  elif name == Event.CMD_EXECUTE:
75
- self.cmd(
76
- ctx,
77
- data['commands'],
78
- )
65
+ self.cmd(ctx, data['commands'])
79
66
 
80
67
  def cmd_syntax(self, data: dict):
81
68
  """
@@ -83,9 +70,10 @@ class Plugin(BasePlugin):
83
70
 
84
71
  :param data: event data dict
85
72
  """
73
+ append = data['cmd'].append
86
74
  for option in self.allowed_cmds:
87
75
  if self.has_cmd(option):
88
- data['cmd'].append(self.get_cmd(option)) # append command
76
+ append(self.get_cmd(option)) # append command
89
77
 
90
78
  def cmd(self, ctx: CtxItem, cmds: list):
91
79
  """
@@ -94,28 +82,25 @@ class Plugin(BasePlugin):
94
82
  :param ctx: CtxItem
95
83
  :param cmds: commands dict
96
84
  """
97
- is_cmd = False
98
- my_commands = []
99
- for item in cmds:
100
- if item["cmd"] in self.allowed_cmds:
101
- my_commands.append(item)
102
- is_cmd = True
103
-
104
- if not is_cmd:
85
+ my_commands = [item for item in cmds if item.get("cmd") in self.allowed_cmds]
86
+ if not my_commands:
105
87
  return
106
88
 
107
89
  response = None
90
+ now_str = None
91
+
108
92
  for item in my_commands:
109
93
  try:
110
- if item["cmd"] in self.allowed_cmds and self.has_cmd(item["cmd"]):
111
- # get time
112
- if item["cmd"] == "get_time":
113
- time = datetime.now().strftime('%A, %Y-%m-%d %H:%M:%S')
94
+ cmd_name = item.get("cmd")
95
+ if cmd_name in self.allowed_cmds and self.has_cmd(cmd_name):
96
+ if cmd_name == "get_time":
97
+ if now_str is None:
98
+ now_str = datetime.now().strftime('%A, %Y-%m-%d %H:%M:%S')
114
99
  response = {
115
100
  "request": {
116
- "cmd": item["cmd"]
101
+ "cmd": cmd_name
117
102
  },
118
- "result": time,
103
+ "result": now_str,
119
104
  }
120
105
  except Exception as e:
121
106
  self.error(e)
@@ -131,18 +116,23 @@ class Plugin(BasePlugin):
131
116
  :param silent: silent mode (no logs)
132
117
  :return: updated prompt
133
118
  """
134
- if self.get_option_value("hour") or self.get_option_value("date"):
135
- if prompt.strip() != "":
119
+ get_opt = self.get_option_value
120
+ hour = get_opt("hour")
121
+ date = get_opt("date")
122
+
123
+ if hour or date:
124
+ if prompt and not prompt.isspace():
136
125
  prompt += "\n\n"
137
- if self.get_option_value("hour") and self.get_option_value("date"):
138
- prompt += self.get_option_value("tpl").\
139
- format(time=datetime.now().strftime('%A, %Y-%m-%d %H:%M:%S'))
140
- elif self.get_option_value("hour"):
141
- prompt += self.get_option_value("tpl").\
142
- format(time=datetime.now().strftime('%H:%M:%S'))
143
- elif self.get_option_value("date"):
144
- prompt += self.get_option_value("tpl").\
145
- format(time=datetime.now().strftime('%A, %Y-%m-%d'))
126
+
127
+ tpl = get_opt("tpl")
128
+ now = datetime.now()
129
+
130
+ if hour and date:
131
+ prompt += tpl.format(time=now.strftime('%A, %Y-%m-%d %H:%M:%S'))
132
+ elif hour:
133
+ prompt += tpl.format(time=now.strftime('%H:%M:%S'))
134
+ elif date:
135
+ prompt += tpl.format(time=now.strftime('%A, %Y-%m-%d'))
146
136
  return prompt
147
137
 
148
138
  def on_agent_prompt(self, prompt: str, silent: bool = False) -> str:
@@ -153,16 +143,18 @@ class Plugin(BasePlugin):
153
143
  :param silent: silent mode (no logs)
154
144
  :return: updated prompt
155
145
  """
156
- if self.get_option_value("hour") or self.get_option_value("date"):
157
- if self.get_option_value("hour") and self.get_option_value("date"):
158
- prompt = self.get_option_value("tpl").\
159
- format(time=datetime.now().strftime('%A, %Y-%m-%d %H:%M:%S')) + "\n\n" + prompt
160
- elif self.get_option_value("hour"):
161
- prompt = self.get_option_value("tpl").\
162
- format(time=datetime.now().strftime('%H:%M:%S') + "\n\n" + prompt)
163
- elif self.get_option_value("date"):
164
- prompt = self.get_option_value("tpl").\
165
- format(time=datetime.now().strftime('%A, %Y-%m-%d')) + "\n\n" + prompt
166
- return prompt
167
-
168
-
146
+ get_opt = self.get_option_value
147
+ hour = get_opt("hour")
148
+ date = get_opt("date")
149
+
150
+ if hour or date:
151
+ tpl = get_opt("tpl")
152
+ now = datetime.now()
153
+
154
+ if hour and date:
155
+ prompt = tpl.format(time=now.strftime('%A, %Y-%m-%d %H:%M:%S')) + "\n\n" + prompt
156
+ elif hour:
157
+ prompt = tpl.format(time=now.strftime('%H:%M:%S') + "\n\n" + prompt)
158
+ elif date:
159
+ prompt = tpl.format(time=now.strftime('%A, %Y-%m-%d')) + "\n\n" + prompt
160
+ return prompt
@@ -6,17 +6,14 @@
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.07.14 00:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
- import os
13
-
14
12
  from pygpt_net.plugin.base.plugin import BasePlugin
15
13
  from pygpt_net.core.events import Event
16
14
  from pygpt_net.item.ctx import CtxItem
17
15
 
18
16
  from .config import Config
19
- from .worker import Worker
20
17
 
21
18
 
22
19
  class Plugin(BasePlugin):
@@ -88,6 +85,8 @@ class Plugin(BasePlugin):
88
85
  :param ctx: CtxItem
89
86
  :param cmds: commands dict
90
87
  """
88
+ from .worker import Worker
89
+
91
90
  is_cmd = False
92
91
  my_commands = []
93
92
  for item in cmds:
@@ -6,17 +6,14 @@
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.07.14 00:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
- import os
13
-
14
12
  from pygpt_net.plugin.base.plugin import BasePlugin
15
13
  from pygpt_net.core.events import Event
16
14
  from pygpt_net.item.ctx import CtxItem
17
15
 
18
16
  from .config import Config
19
- from .worker import Worker
20
17
 
21
18
 
22
19
  class Plugin(BasePlugin):
@@ -90,6 +87,8 @@ class Plugin(BasePlugin):
90
87
  :param ctx: CtxItem
91
88
  :param cmds: commands dict
92
89
  """
90
+ from .worker import Worker
91
+
93
92
  is_cmd = False
94
93
  my_commands = []
95
94
  for item in cmds:
@@ -6,17 +6,14 @@
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.07.14 00:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
- import os
13
-
14
12
  from pygpt_net.plugin.base.plugin import BasePlugin
15
13
  from pygpt_net.core.events import Event
16
14
  from pygpt_net.item.ctx import CtxItem
17
15
 
18
16
  from .config import Config
19
- from .worker import Worker
20
17
 
21
18
 
22
19
  class Plugin(BasePlugin):
@@ -98,6 +95,8 @@ class Plugin(BasePlugin):
98
95
  :param ctx: CtxItem
99
96
  :param cmds: commands dict
100
97
  """
98
+ from .worker import Worker
99
+
101
100
  is_cmd = False
102
101
  my_commands = []
103
102
  for item in cmds:
@@ -6,11 +6,9 @@
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.08.11 00:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
- import re
13
-
14
12
  from PySide6.QtCore import Qt, QObject, Signal, Slot, QEvent
15
13
  from PySide6.QtWebChannel import QWebChannel
16
14
  from PySide6.QtWebEngineCore import QWebEngineSettings, QWebEnginePage, QWebEngineProfile
@@ -101,7 +99,6 @@ class ChatWebOutput(QWebEngineView):
101
99
 
102
100
  self.setPage(new_page)
103
101
  self._teardown_page(old_page)
104
- # self.setUpdatesEnabled(True)
105
102
 
106
103
  mem_clean()
107
104
 
@@ -232,12 +229,12 @@ class ChatWebOutput(QWebEngineView):
232
229
 
233
230
  # save as (all) - plain (lazy normalization only on click)
234
231
  action = QAction(QIcon(":/icons/save.svg"), trans('action.save_as') + " (text)", self)
235
- action.triggered.connect(lambda: self.signals.save_as.emit(re.sub(r'\n{2,}', '\n\n', self.plain), 'txt'))
232
+ action.triggered.connect(self._save_as_text)
236
233
  menu.addAction(action)
237
234
 
238
235
  # save as (all) - html
239
236
  action = QAction(QIcon(":/icons/save.svg"), trans('action.save_as') + " (html)", self)
240
- action.triggered.connect(lambda: self.signals.save_as.emit(re.sub(r'\n{2,}', '\n\n', self.html_content), 'html'))
237
+ action.triggered.connect(self._save_as_html)
241
238
  menu.addAction(action)
242
239
 
243
240
  action = QAction(QIcon(":/icons/search.svg"), trans('text.context_menu.find'), self)
@@ -246,6 +243,21 @@ class ChatWebOutput(QWebEngineView):
246
243
 
247
244
  menu.exec_(self.mapToGlobal(position))
248
245
 
246
+ @Slot()
247
+ def _save_as_text(self):
248
+ """
249
+ Save current content as text file
250
+ """
251
+ # TODO: normalize text (remove extra spaces, newlines, etc.)
252
+ self.page().toPlainText(lambda txt: self.signals.save_as.emit(txt, 'txt'))
253
+
254
+ @Slot()
255
+ def _save_as_html(self):
256
+ """
257
+ Save current content as HTML file
258
+ """
259
+ self.page().toHtml(lambda html: self.signals.save_as.emit(html, 'html'))
260
+
249
261
  def update_zoom(self):
250
262
  """Update zoom from config"""
251
263
  try:
@@ -275,14 +287,6 @@ class ChatWebOutput(QWebEngineView):
275
287
  self.plain = ""
276
288
  self.html_content = ""
277
289
 
278
- def update_current_content(self):
279
- """Update current content"""
280
- p = self.page()
281
- if not p:
282
- return
283
- p.runJavaScript("document.getElementById('container')?.outerHTML ?? ''", 0, self.set_plaintext)
284
- p.runJavaScript("document.documentElement.innerHTML", 0, self.set_html_content)
285
-
286
290
  def on_page_loaded(self, success):
287
291
  """
288
292
  Page loaded event handler
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pygpt-net
3
- Version: 2.6.3
3
+ Version: 2.6.4
4
4
  Summary: Desktop AI Assistant powered by: OpenAI GPT-5, o1, o3, GPT-4, 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: py_gpt,py-gpt,pygpt,desktop,app,o1,o3,gpt-5,gpt,gpt4,gpt-4o,gpt-4v,gpt3.5,gpt-4,gpt-4-vision,gpt-3.5,llama3,mistral,gemini,grok,deepseek,bielik,claude,tts,whisper,vision,chatgpt,dall-e,chat,chatbot,assistant,text completion,image generation,ai,api,openai,api key,langchain,llama-index,ollama,presets,ui,qt,pyside
@@ -108,7 +108,7 @@ Description-Content-Type: text/markdown
108
108
 
109
109
  [![pygpt](https://snapcraft.io/pygpt/badge.svg)](https://snapcraft.io/pygpt)
110
110
 
111
- Release: **2.6.3** | build: **2025-08-15* | Python: **>=3.10, <3.14**
111
+ Release: **2.6.4** | build: **2025-08-15** | Python: **>=3.10, <3.14**
112
112
 
113
113
  > Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
114
114
  >
@@ -4514,6 +4514,11 @@ may consume additional tokens that are not displayed in the main window.
4514
4514
 
4515
4515
  ## Recent changes:
4516
4516
 
4517
+ **2.6.4 (2025-08-15)**
4518
+
4519
+ - Fix: tool execution in OpenAI Agents.
4520
+ - Optimizations.
4521
+
4517
4522
  **2.6.3 (2025-08-15)**
4518
4523
 
4519
4524
  - Optimized streaming and CPU usage.