pygpt-net 2.6.0.post2__py3-none-any.whl → 2.6.2__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 (98) hide show
  1. pygpt_net/CHANGELOG.txt +8 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +27 -9
  4. pygpt_net/controller/chat/response.py +10 -4
  5. pygpt_net/controller/chat/stream.py +40 -2
  6. pygpt_net/controller/model/editor.py +45 -4
  7. pygpt_net/controller/plugins/plugins.py +25 -0
  8. pygpt_net/controller/presets/editor.py +100 -100
  9. pygpt_net/controller/presets/experts.py +20 -1
  10. pygpt_net/controller/presets/presets.py +5 -4
  11. pygpt_net/controller/ui/mode.py +17 -66
  12. pygpt_net/core/agents/provider.py +2 -1
  13. pygpt_net/core/agents/runner.py +123 -9
  14. pygpt_net/core/agents/runners/helpers.py +3 -2
  15. pygpt_net/core/agents/runners/llama_workflow.py +176 -22
  16. pygpt_net/core/agents/runners/loop.py +22 -13
  17. pygpt_net/core/experts/experts.py +19 -25
  18. pygpt_net/core/idx/chat.py +24 -34
  19. pygpt_net/core/idx/response.py +5 -2
  20. pygpt_net/core/locale/locale.py +73 -45
  21. pygpt_net/core/render/web/body.py +152 -207
  22. pygpt_net/core/render/web/renderer.py +4 -2
  23. pygpt_net/data/config/config.json +3 -3
  24. pygpt_net/data/config/models.json +3 -3
  25. pygpt_net/data/locale/locale.de.ini +12 -8
  26. pygpt_net/data/locale/locale.en.ini +12 -8
  27. pygpt_net/data/locale/locale.es.ini +12 -8
  28. pygpt_net/data/locale/locale.fr.ini +12 -8
  29. pygpt_net/data/locale/locale.it.ini +12 -8
  30. pygpt_net/data/locale/locale.pl.ini +12 -8
  31. pygpt_net/data/locale/locale.uk.ini +12 -8
  32. pygpt_net/data/locale/locale.zh.ini +12 -8
  33. pygpt_net/item/ctx.py +2 -1
  34. pygpt_net/plugin/base/plugin.py +35 -3
  35. pygpt_net/plugin/bitbucket/__init__.py +12 -0
  36. pygpt_net/plugin/bitbucket/config.py +267 -0
  37. pygpt_net/plugin/bitbucket/plugin.py +125 -0
  38. pygpt_net/plugin/bitbucket/worker.py +569 -0
  39. pygpt_net/plugin/cmd_files/worker.py +19 -16
  40. pygpt_net/plugin/facebook/__init__.py +12 -0
  41. pygpt_net/plugin/facebook/config.py +359 -0
  42. pygpt_net/plugin/facebook/plugin.py +114 -0
  43. pygpt_net/plugin/facebook/worker.py +698 -0
  44. pygpt_net/plugin/github/__init__.py +12 -0
  45. pygpt_net/plugin/github/config.py +441 -0
  46. pygpt_net/plugin/github/plugin.py +124 -0
  47. pygpt_net/plugin/github/worker.py +674 -0
  48. pygpt_net/plugin/google/__init__.py +12 -0
  49. pygpt_net/plugin/google/config.py +367 -0
  50. pygpt_net/plugin/google/plugin.py +126 -0
  51. pygpt_net/plugin/google/worker.py +826 -0
  52. pygpt_net/plugin/slack/__init__.py +12 -0
  53. pygpt_net/plugin/slack/config.py +349 -0
  54. pygpt_net/plugin/slack/plugin.py +116 -0
  55. pygpt_net/plugin/slack/worker.py +639 -0
  56. pygpt_net/plugin/telegram/__init__.py +12 -0
  57. pygpt_net/plugin/telegram/config.py +308 -0
  58. pygpt_net/plugin/telegram/plugin.py +118 -0
  59. pygpt_net/plugin/telegram/worker.py +563 -0
  60. pygpt_net/plugin/twitter/__init__.py +12 -0
  61. pygpt_net/plugin/twitter/config.py +491 -0
  62. pygpt_net/plugin/twitter/plugin.py +126 -0
  63. pygpt_net/plugin/twitter/worker.py +837 -0
  64. pygpt_net/provider/agents/base.py +4 -1
  65. pygpt_net/provider/agents/llama_index/codeact_workflow.py +95 -0
  66. pygpt_net/provider/agents/llama_index/legacy/__init__.py +0 -0
  67. pygpt_net/provider/agents/llama_index/{openai.py → legacy/openai.py} +2 -2
  68. pygpt_net/provider/agents/llama_index/{openai_assistant.py → legacy/openai_assistant.py} +37 -5
  69. pygpt_net/provider/agents/llama_index/{planner.py → legacy/planner.py} +3 -3
  70. pygpt_net/provider/agents/llama_index/{react.py → legacy/react.py} +3 -3
  71. pygpt_net/provider/agents/llama_index/openai_workflow.py +52 -0
  72. pygpt_net/provider/agents/llama_index/planner_workflow.py +115 -0
  73. pygpt_net/provider/agents/llama_index/react_workflow.py +6 -4
  74. pygpt_net/provider/agents/llama_index/workflow/__init__.py +0 -0
  75. pygpt_net/provider/agents/llama_index/{codeact_agent_custom.py → workflow/codeact.py} +124 -8
  76. pygpt_net/provider/agents/llama_index/workflow/events.py +24 -0
  77. pygpt_net/provider/agents/llama_index/workflow/openai.py +634 -0
  78. pygpt_net/provider/agents/llama_index/workflow/planner.py +601 -0
  79. pygpt_net/provider/agents/openai/agent.py +1 -0
  80. pygpt_net/provider/agents/openai/agent_b2b.py +2 -0
  81. pygpt_net/provider/agents/openai/agent_planner.py +1 -0
  82. pygpt_net/provider/agents/openai/agent_with_experts.py +1 -0
  83. pygpt_net/provider/agents/openai/agent_with_experts_feedback.py +1 -0
  84. pygpt_net/provider/agents/openai/agent_with_feedback.py +1 -0
  85. pygpt_net/provider/agents/openai/evolve.py +1 -0
  86. pygpt_net/provider/core/preset/patch.py +11 -17
  87. pygpt_net/ui/base/config_dialog.py +4 -0
  88. pygpt_net/ui/dialog/preset.py +34 -77
  89. pygpt_net/ui/layout/toolbox/presets.py +2 -2
  90. pygpt_net/ui/main.py +3 -1
  91. pygpt_net/ui/widget/lists/experts.py +3 -2
  92. {pygpt_net-2.6.0.post2.dist-info → pygpt_net-2.6.2.dist-info}/METADATA +155 -4
  93. {pygpt_net-2.6.0.post2.dist-info → pygpt_net-2.6.2.dist-info}/RECORD +96 -62
  94. pygpt_net/data/config/presets/agent_react_workflow.json +0 -34
  95. pygpt_net/provider/agents/llama_index/code_act.py +0 -58
  96. {pygpt_net-2.6.0.post2.dist-info → pygpt_net-2.6.2.dist-info}/LICENSE +0 -0
  97. {pygpt_net-2.6.0.post2.dist-info → pygpt_net-2.6.2.dist-info}/WHEEL +0 -0
  98. {pygpt_net-2.6.0.post2.dist-info → pygpt_net-2.6.2.dist-info}/entry_points.txt +0 -0
@@ -38,10 +38,12 @@ class Patch:
38
38
  is_bot = False
39
39
  is_evolve = False
40
40
  is_b2b = False
41
+ is_workflow = False
41
42
 
42
43
  for k in self.window.core.presets.items:
43
44
  data = self.window.core.presets.items[k]
44
45
  updated = False
46
+ save = False
45
47
 
46
48
  # get version of preset
47
49
  if data.version is None or data.version == "":
@@ -150,23 +152,6 @@ class Patch:
150
152
  updated = True
151
153
  is_agent_code_act = True # prevent multiple copies
152
154
 
153
- # < 2.5.38
154
- if old < parse_version("2.5.38"):
155
- if 'agent_react_workflow' not in self.window.core.presets.items and not is_agent_react_workflow:
156
- print("Migrating preset file from < 2.5.38...")
157
- files = [
158
- 'agent_react_workflow.json',
159
- ]
160
- for file in files:
161
- dst = os.path.join(self.window.core.config.get_user_dir('presets'), file)
162
- src = os.path.join(self.window.core.config.get_app_path(), 'data', 'config',
163
- 'presets', file)
164
- shutil.copyfile(src, dst)
165
- print("Patched file: {}.".format(dst))
166
-
167
- updated = True
168
- is_agent_react_workflow = True # prevent multiple copies
169
-
170
155
  # < 2.5.71
171
156
  if old < parse_version("2.5.71"):
172
157
  if 'current.computer' not in self.window.core.presets.items and not is_computer:
@@ -249,8 +234,17 @@ class Patch:
249
234
  updated = True
250
235
  is_b2b = True # prevent multiple copies
251
236
 
237
+ # < 2.6.1
238
+ if old < parse_version("2.6.1"):
239
+ if data.agent_provider == "react_workflow":
240
+ data.agent_provider = "react"
241
+ updated = True
242
+ save = True
243
+
252
244
  # update file
253
245
  if updated:
246
+ if save:
247
+ self.window.core.presets.save(k)
254
248
  self.window.core.presets.load() # reload presets from patched files
255
249
  self.window.core.presets.save(k) # re-save presets
256
250
  migrated = True
@@ -42,10 +42,14 @@ class BaseConfigDialog:
42
42
  :return: settings widgets
43
43
  """
44
44
  widgets = {}
45
+ kwargs = kwargs if kwargs is not None else {}
45
46
 
46
47
  for key in options:
47
48
  option = options[key]
48
49
 
50
+ if "excluded" in kwargs and kwargs['excluded'] is not None and key in kwargs['excluded']:
51
+ continue
52
+
49
53
  # create widget by option type
50
54
  if option['type'] == 'text' or option['type'] == 'int' or option['type'] == 'float':
51
55
  if 'slider' in option and option['slider'] and (option['type'] == 'int' or option['type'] == 'float'):
@@ -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.08.09 19:00:00 #
9
+ # Updated Date: 2025.08.14 13:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt
@@ -72,18 +72,17 @@ class Preset(BaseConfigDialog):
72
72
  fields = self.window.controller.presets.editor.get_options()
73
73
 
74
74
  # build settings widgets
75
- widgets = self.build_widgets(self.id, fields) # from base config dialog
75
+ widgets = self.build_widgets(self.id, fields, excluded=["tool.function"]) # from base config dialog
76
76
 
77
77
  # apply settings widgets
78
78
  for key in widgets:
79
79
  self.window.ui.config[self.id][key] = widgets[key]
80
80
 
81
- # btn: add function
82
- self.window.ui.config[self.id]['tool.function'].add_btn.setText(trans('assistant.func.add'))
83
-
84
81
  # apply widgets to layouts
85
82
  options = {}
86
83
  for key in widgets:
84
+ if key == "tool.function":
85
+ continue
87
86
  if fields[key]["type"] in ['text', 'int', 'float']:
88
87
  # if key != "prompt": # built separately
89
88
  options[key] = self.add_option(widgets[key], fields[key])
@@ -97,7 +96,6 @@ class Preset(BaseConfigDialog):
97
96
  widgets[key].setMinimumHeight(100)
98
97
  options[key] = self.add_row_option(widgets[key], fields[key])
99
98
  elif fields[key]["type"] == 'bool':
100
- # widgets[key].setMaximumHeight(38)
101
99
  options[key] = self.add_raw_option(widgets[key], fields[key])
102
100
  elif fields[key]["type"] == 'dict':
103
101
  options[key] = self.add_row_option(widgets[key], fields[key])
@@ -106,8 +104,6 @@ class Preset(BaseConfigDialog):
106
104
  elif fields[key]["type"] == 'bool_list':
107
105
  options[key] = self.add_row_option(widgets[key], fields[key])
108
106
 
109
- self.window.ui.nodes['preset.tool.function.label'].setVisible(False) # hide label
110
-
111
107
  rows = QVBoxLayout()
112
108
 
113
109
  for key in options:
@@ -156,68 +152,31 @@ class Preset(BaseConfigDialog):
156
152
  rows_mode.addLayout(rows_mode_middle)
157
153
  rows_mode.addLayout(rows_mode_right)
158
154
  rows_mode.setAlignment(Qt.AlignTop)
155
+ rows_mode.setContentsMargins(0, 0, 0, 0)
159
156
  rows_mode.addStretch(1)
160
157
 
161
158
  # modes
162
159
  self.window.ui.nodes['preset.editor.modes'] = QWidget()
163
160
  self.window.ui.nodes['preset.editor.modes'].setLayout(rows_mode)
164
161
  self.window.ui.nodes['preset.editor.modes'].setContentsMargins(0, 0, 0, 0)
165
- # self.window.ui.nodes['preset.editor.modes'].setMaximumWidth(300)
166
-
167
- # functions label
168
- self.window.ui.nodes['preset.tool.function.label.all'] = HelpLabel(
169
- trans("preset.tool.function.tip.all"))
170
- self.window.ui.nodes['preset.tool.function.label.all'].setAlignment(Qt.AlignCenter)
171
- self.window.ui.nodes['preset.tool.function.label.assistant'] = HelpLabel(
172
- trans("preset.tool.function.tip.assistant"))
173
- self.window.ui.nodes['preset.tool.function.label.assistant'].setAlignment(Qt.AlignCenter)
174
- self.window.ui.nodes['preset.tool.function.label.agent_llama'] = HelpLabel(
175
- trans("preset.tool.function.tip.agent_llama"))
176
- self.window.ui.nodes['preset.tool.function.label.agent_llama'].setAlignment(Qt.AlignCenter)
177
-
178
- # functions
179
- self.window.ui.nodes['preset.editor.functions'] = QWidget()
180
- self.window.ui.nodes['preset.editor.functions'].setLayout(options["tool.function"])
181
162
 
182
163
  # experts
183
164
  self.window.ui.nodes['preset.editor.experts'] = ExpertsEditor(self.window)
184
165
 
185
- # agents - llama index
186
- agent_keys = [
187
- "idx",
188
- "assistant_id",
189
- ]
190
- agent_layout = QVBoxLayout()
191
- agent_layout.setContentsMargins(0, 0, 0, 0)
192
- for key in agent_keys:
193
- widget = QWidget()
194
- widget.setLayout(options[key])
195
- agent_layout.addWidget(widget)
196
- agent_layout.addStretch()
197
- self.window.ui.nodes['preset.editor.agent_llama'] = QWidget()
198
- self.window.ui.nodes['preset.editor.agent_llama'].setLayout(agent_layout)
199
- self.window.ui.nodes['preset.editor.agent_llama'].setContentsMargins(20, 0, 0, 30)
200
-
201
166
  # desc and prompt
202
-
203
167
  self.window.ui.nodes['preset.editor.description'] = QWidget()
204
168
  self.window.ui.nodes['preset.editor.description'].setLayout(options['description'])
205
169
  self.window.ui.nodes['preset.editor.description'].setContentsMargins(0, 5, 0, 5)
206
- ''''
207
- self.window.ui.nodes['preset.editor.remote_tools'] = QWidget()
208
- self.window.ui.nodes['preset.editor.remote_tools'].setLayout(options['remote_tools'])
209
- self.window.ui.nodes['preset.editor.remote_tools'].setContentsMargins(0, 0, 0, 0)
210
- '''
211
170
 
212
171
  # prompt + extra options
213
172
  prompt_layout = QVBoxLayout()
214
173
  prompt_layout.addWidget(widgets['prompt'])
215
174
  prompt_layout.setContentsMargins(0, 10, 0, 10)
175
+
216
176
  footer_layout = self.prepare_extra_config(prompt_layout)
217
177
 
218
178
  prompt_layout = QVBoxLayout()
219
179
  prompt_layout.setContentsMargins(0, 0, 0, 0)
220
- # prompt_layout.addWidget(self.window.ui.nodes['preset.editor.remote_tools'])
221
180
  prompt_layout.addWidget(self.window.ui.nodes['preset.editor.description'])
222
181
  prompt_layout.addLayout(footer_layout)
223
182
 
@@ -234,7 +193,7 @@ class Preset(BaseConfigDialog):
234
193
  "temperature",
235
194
  "agent_provider",
236
195
  "agent_provider_openai",
237
- "remote_tools",
196
+ "idx",
238
197
  ]
239
198
  personalize_keys = [
240
199
  "ai_name",
@@ -248,6 +207,18 @@ class Preset(BaseConfigDialog):
248
207
  self.window.ui.nodes['preset.editor.' + key].setContentsMargins(0, 0, 0, 0)
249
208
  rows.addWidget(self.window.ui.nodes['preset.editor.' + key])
250
209
 
210
+ # remote tools
211
+ self.window.ui.nodes['preset.editor.remote_tools'] = QWidget()
212
+ self.window.ui.nodes['preset.editor.remote_tools'].setLayout(options['remote_tools'])
213
+ self.window.ui.nodes['preset.editor.remote_tools'].setContentsMargins(0, 0, 0, 0)
214
+
215
+ rows_remote_tools = QVBoxLayout()
216
+ rows_remote_tools.addWidget(self.window.ui.nodes['preset.editor.remote_tools'])
217
+ rows_remote_tools.addStretch(1)
218
+
219
+ widget_remote_tools = QWidget()
220
+ widget_remote_tools.setLayout(rows_remote_tools)
221
+
251
222
  # personalize
252
223
  personalize_rows = QVBoxLayout()
253
224
  for key in personalize_keys:
@@ -267,40 +238,18 @@ class Preset(BaseConfigDialog):
267
238
  personalize_rows.addStretch(1)
268
239
  personalize_rows.addWidget(warn_label)
269
240
 
270
- self.window.ui.nodes['preset.editor.remote_tools'].setMinimumHeight(140)
271
-
272
241
  rows.setContentsMargins(0, 0, 0, 0)
273
242
  rows.addStretch(1)
274
243
  rows.setAlignment(Qt.AlignTop)
244
+
275
245
  widget_base = QWidget()
276
246
  widget_base.setLayout(rows)
277
247
  widget_base.setMinimumWidth(300)
278
248
 
279
- func_tip_layout = QVBoxLayout()
280
- func_tip_layout.addWidget(self.window.ui.nodes['preset.tool.function.label.all'])
281
- func_tip_layout.addWidget(self.window.ui.nodes['preset.tool.function.label.assistant'])
282
- func_tip_layout.addWidget(self.window.ui.nodes['preset.tool.function.label.agent_llama'])
283
- func_tip_layout.setContentsMargins(0, 0, 0, 0)
284
- func_tip_widget = QWidget()
285
- func_tip_widget.setLayout(func_tip_layout)
286
-
287
- func_rows = QVBoxLayout()
288
- func_rows.addWidget(self.window.ui.nodes['preset.editor.functions'])
289
- func_rows.addWidget(self.window.ui.nodes['preset.editor.experts'])
290
- func_rows.addWidget(self.window.ui.nodes['preset.editor.agent_llama'])
291
- #func_rows.addStretch()
292
- func_rows.addWidget(func_tip_widget)
293
-
294
- func_rows.setContentsMargins(0, 0, 0, 0)
295
- func_widget = QWidget()
296
- func_widget.setLayout(func_rows)
297
- #func_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
298
- #self.window.ui.nodes['preset.editor.functions'].setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
299
249
  self.window.ui.nodes['preset.editor.experts'].setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
300
250
 
301
251
  main = QHBoxLayout()
302
252
  main.addWidget(widget_base)
303
- main.addWidget(func_widget)
304
253
  main.addWidget(self.window.ui.nodes['preset.editor.modes'])
305
254
 
306
255
  widget_main = QWidget()
@@ -311,17 +260,24 @@ class Preset(BaseConfigDialog):
311
260
  self.window.ui.splitters['editor.presets'].addWidget(widget_prompt)
312
261
  self.window.ui.splitters['editor.presets'].setStretchFactor(0, 1)
313
262
  self.window.ui.splitters['editor.presets'].setStretchFactor(1, 2)
314
- #self.window.ui.splitters['editor.presets'].setChildrenCollapsible(False)
315
263
 
316
264
  widget_personalize = QWidget()
317
265
  widget_personalize.setLayout(personalize_rows)
318
266
 
319
- tabs = QTabWidget()
320
- tabs.addTab(self.window.ui.splitters['editor.presets'], trans("preset.tab.general"))
321
- tabs.addTab(widget_personalize, trans("preset.tab.personalize"))
267
+ experts_rows = QVBoxLayout()
268
+ experts_rows.addWidget(self.window.ui.nodes['preset.editor.experts'])
269
+
270
+ widget_experts = QWidget()
271
+ widget_experts.setLayout(experts_rows)
272
+
273
+ self.window.ui.tabs['preset.editor.tabs'] = QTabWidget()
274
+ self.window.ui.tabs['preset.editor.tabs'].addTab(self.window.ui.splitters['editor.presets'], trans("preset.tab.general"))
275
+ self.window.ui.tabs['preset.editor.tabs'].addTab(widget_personalize, trans("preset.tab.personalize"))
276
+ self.window.ui.tabs['preset.editor.tabs'].addTab(widget_experts, trans("preset.tab.experts"))
277
+ self.window.ui.tabs['preset.editor.tabs'].addTab(widget_remote_tools, trans("preset.tab.remote_tools"))
322
278
 
323
279
  layout = QVBoxLayout()
324
- layout.addWidget(tabs)
280
+ layout.addWidget(self.window.ui.tabs['preset.editor.tabs'])
325
281
  layout.addLayout(footer)
326
282
 
327
283
  self.window.ui.dialog['editor.' + self.dialog_id] = EditorDialog(self.window, self.dialog_id)
@@ -343,8 +299,9 @@ class Preset(BaseConfigDialog):
343
299
  prompt_layout.setContentsMargins(0, 10, 0, 10)
344
300
  prompt_widget = QWidget()
345
301
  prompt_widget.setLayout(prompt_layout)
346
- self.window.ui.tabs['preset.editor.extra'] = QTabWidget()
302
+
347
303
  self.window.ui.nodes['preset.editor.extra'] = {}
304
+ self.window.ui.tabs['preset.editor.extra'] = QTabWidget()
348
305
  self.window.ui.tabs['preset.editor.extra'].addTab(
349
306
  prompt_widget,
350
307
  trans("preset.prompt"),
@@ -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.21 20:00:00 #
9
+ # Updated Date: 2025.08.14 13:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6 import QtCore
@@ -146,4 +146,4 @@ class Presets:
146
146
  new_model.setData(index, name)
147
147
  i += 1
148
148
 
149
- self.window.ui.nodes[self.id].restore_selection()
149
+ self.window.ui.nodes[self.id].restore_selection()
pygpt_net/ui/main.py CHANGED
@@ -285,7 +285,7 @@ class MainWindow(QMainWindow, QtStyleTools):
285
285
  This method is called when the application is closing.
286
286
  """
287
287
  if self.is_closing:
288
- print("Application is already closing.")
288
+ print("Application is already closing...")
289
289
  return
290
290
  self.is_closing = True
291
291
  print("Closing...")
@@ -301,6 +301,8 @@ class MainWindow(QMainWindow, QtStyleTools):
301
301
  self.controller.calendar.save_all()
302
302
  print("Saving drawing...")
303
303
  self.controller.painter.save_all()
304
+ print("Saving plugins config...")
305
+ self.controller.plugins.save_all()
304
306
  print("Saving tools...")
305
307
  self.tools.on_exit()
306
308
  print("Saving layout state...")
@@ -73,16 +73,17 @@ class ExpertsEditor(QWidget):
73
73
  self.window.ui.nodes["preset.experts.selected"].clicked.disconnect()
74
74
 
75
75
  available_layout = QVBoxLayout()
76
- available_layout.addWidget(self.window.ui.nodes["preset.experts.available.label"])
77
76
  available_layout.addWidget(self.window.ui.nodes["preset.experts.available"])
77
+ available_layout.addWidget(self.window.ui.nodes["preset.experts.available.label"])
78
78
 
79
79
  selected_layout = QVBoxLayout()
80
- selected_layout.addWidget(self.window.ui.nodes["preset.experts.selected.label"])
81
80
  selected_layout.addWidget(self.window.ui.nodes["preset.experts.selected"])
81
+ selected_layout.addWidget(self.window.ui.nodes["preset.experts.selected.label"])
82
82
 
83
83
  layout.addLayout(available_layout)
84
84
  layout.addLayout(arrows_layout)
85
85
  layout.addLayout(selected_layout)
86
+ layout.setContentsMargins(0, 0, 0, 0)
86
87
  return layout
87
88
 
88
89
  def update_available(self, data):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pygpt-net
3
- Version: 2.6.0.post2
3
+ Version: 2.6.2
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
@@ -31,6 +31,8 @@ Requires-Dist: chromadb (>=0.5.20,<0.6.0)
31
31
  Requires-Dist: croniter (>=2.0.7,<3.0.0)
32
32
  Requires-Dist: docker (>=7.1.0,<8.0.0)
33
33
  Requires-Dist: docx2txt (>=0.8,<0.9)
34
+ Requires-Dist: gkeepapi (>=0.15.1,<0.16.0)
35
+ Requires-Dist: google-api-python-client (>=2.173.0,<3.0.0)
34
36
  Requires-Dist: google-generativeai (>=0.8.5,<0.9.0)
35
37
  Requires-Dist: httpx (>=0.28.1,<0.29.0)
36
38
  Requires-Dist: httpx-socks (>=0.10.1,<0.11.0)
@@ -106,7 +108,7 @@ Description-Content-Type: text/markdown
106
108
 
107
109
  [![pygpt](https://snapcraft.io/pygpt/badge.svg)](https://snapcraft.io/pygpt)
108
110
 
109
- Release: **2.6.0** | build: **2025-08-13** | Python: **>=3.10, <3.14**
111
+ Release: **2.6.2** | build: **2025-08-15* | Python: **>=3.10, <3.14**
110
112
 
111
113
  > Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
112
114
  >
@@ -781,13 +783,17 @@ The vector database in use will be displayed in the list of uploaded files, on t
781
783
 
782
784
  Mode that allows the use of agents offered by `LlamaIndex`.
783
785
 
784
- Includes built-in agents:
786
+ Includes built-in agents (Workflow):
785
787
 
786
- - OpenAI
788
+ - FunctionAgent
787
789
  - ReAct
788
790
  - Structured Planner (sub-tasks)
789
791
  - CodeAct (connected to Code Interpreter plugin)
790
792
 
793
+ Includes built-in agents (Legacy):
794
+
795
+ - OpenAI Assistants
796
+
791
797
  In the future, the list of built-in agents will be expanded.
792
798
 
793
799
  You can also create your own agent by creating a new provider that inherits from `pygpt_net.provider.agents.base`.
@@ -1444,6 +1450,20 @@ as well as list and create directories.
1444
1450
 
1445
1451
  - `Mailer` - Provides the ability to send, receive and read emails.
1446
1452
 
1453
+ - `Google` - Access Gmail, Drive, Calendar, Contacts, YouTube, Keep for managing emails, files, events, notes, video info, and contacts.
1454
+
1455
+ - `Facebook` - Manage user info, pages, posts, and photos on Facebook pages.
1456
+
1457
+ - `Slack` - Handle users, conversations, messages, and files on Slack.
1458
+
1459
+ - `Telegram` - Send messages, photos, and documents; manage chats and contacts.
1460
+
1461
+ - `X/Twitter` - Interact with tweets and users, manage bookmarks and media, perform likes, retweets, and more.
1462
+
1463
+ - `GitHub` - Access GitHub API to manage repositories, issues, and pull requests.
1464
+
1465
+ - `Bitbucket` - Access Bitbucket API to manage repositories, issues, and pull requests.
1466
+
1447
1467
  ## Audio Input
1448
1468
 
1449
1469
  The plugin facilitates speech recognition (by default using the `Whisper` model from OpenAI, `Google` and `Bing` are also available). It allows for voice commands to be relayed to the AI using your own voice. Whisper doesn't require any extra API keys or additional configurations; it uses the main OpenAI key. In the plugin's configuration options, you should adjust the volume level (min energy) at which the plugin will respond to your microphone. Once the plugin is activated, a new `Speak` option will appear at the bottom near the `Send` button - when this is enabled, the application will respond to the voice received from the microphone.
@@ -2741,6 +2761,129 @@ The plugin provides voice control command execution within a conversation.
2741
2761
 
2742
2762
  See the ``Accessibility`` section for more details.
2743
2763
 
2764
+ ## Google (Gmail, Drive, Calendar, Contacts, YT, Keep)
2765
+
2766
+ - Listing recent emails from Gmail.
2767
+ - Listing all emails from Gmail.
2768
+ - Searching emails in Gmail.
2769
+ - Retrieving email details by ID in Gmail.
2770
+ - Sending an email via Gmail.
2771
+ - Listing recent calendar events.
2772
+ - Listing today's calendar events.
2773
+ - Listing tomorrow's calendar events.
2774
+ - Listing all calendar events.
2775
+ - Retrieving calendar events by a specific date.
2776
+ - Adding a new event to the calendar.
2777
+ - Deleting an event from the calendar.
2778
+ - Listing notes from Google Keep.
2779
+ - Adding a new note to Google Keep.
2780
+ - Listing files from Google Drive.
2781
+ - Finding a file in Google Drive by its path.
2782
+ - Downloading a file from Google Drive.
2783
+ - Uploading a file to Google Drive.
2784
+ - Retrieving information about a YouTube video.
2785
+ - Retrieving the transcript of a YouTube video.
2786
+ - Listing contacts from Google Contacts.
2787
+ - Adding a new contact to Google Contacts.
2788
+
2789
+ ## Facebook
2790
+
2791
+ - Retrieving basic information about the authenticated user.
2792
+ - Listing all Facebook pages the user has access to.
2793
+ - Setting a specified Facebook page as the default.
2794
+ - Retrieving a list of posts from a Facebook page.
2795
+ - Creating a new post on a Facebook page.
2796
+ - Deleting a post from a Facebook page.
2797
+ - Uploading a photo to a Facebook page.
2798
+
2799
+ ## Slack
2800
+
2801
+ - Retrieving a list of users.
2802
+ - Listing all conversations.
2803
+ - Accessing conversation history.
2804
+ - Retrieving conversation replies.
2805
+ - Opening a conversation.
2806
+ - Posting a message in a chat.
2807
+ - Deleting a chat message.
2808
+ - Uploading files to Slack.
2809
+
2810
+ ## Telegram
2811
+
2812
+ - Sending text messages to a chat or channel.
2813
+ - Sending photos with an optional caption to a chat or channel.
2814
+ - Sending documents or files to a chat or channel.
2815
+ - Retrieving information about a specific chat or channel.
2816
+ - Polling for updates in bot mode.
2817
+ - Downloading files using a file identifier.
2818
+ - Listing contacts in user mode.
2819
+ - Listing recent dialogs or chats in user mode.
2820
+ - Retrieving recent messages from a specific chat or channel in user mode.
2821
+
2822
+ ## X/Twitter
2823
+
2824
+ - Retrieve user details by providing their username.
2825
+ - Fetch user information using their unique ID.
2826
+ - Access recent tweets from a specific user.
2827
+ - Search for recent tweets using specific keywords or hashtags.
2828
+ - Create a new tweet and post it on the platform.
2829
+ - Remove an existing tweet from your profile.
2830
+ - Reply to a specific tweet with a new comment.
2831
+ - Quote a tweet while adding your own comments or thoughts.
2832
+ - Like a tweet to show appreciation or support.
2833
+ - Remove a like from a previously liked tweet.
2834
+ - Retweet a tweet to share it with your followers.
2835
+ - Undo a retweet to remove it from your profile.
2836
+ - Hide a specific reply to a tweet.
2837
+ - List all bookmarked tweets for easy access.
2838
+ - Add a tweet to your bookmarks for later reference.
2839
+ - Remove a tweet from your bookmarks.
2840
+ - Upload media files such as images or videos for tweeting.
2841
+ - Set alternative text for uploaded media for accessibility.
2842
+
2843
+ ## GitHub
2844
+
2845
+ - Retrieve details about your GitHub profile.
2846
+ - Get information about a specific GitHub user.
2847
+ - List repositories for a user or organization.
2848
+ - Retrieve details about a specific repository.
2849
+ - Create a new repository.
2850
+ - Delete an existing repository.
2851
+ - Retrieve the contents of a file in a repository.
2852
+ - Upload or update a file in a repository.
2853
+ - Delete a file from a repository.
2854
+ - List issues in a repository.
2855
+ - Create a new issue in a repository.
2856
+ - Add a comment to an existing issue.
2857
+ - Close an existing issue.
2858
+ - List pull requests in a repository.
2859
+ - Create a new pull request.
2860
+ - Merge an existing pull request.
2861
+ - Search for repositories based on a query.
2862
+ - Search for issues based on a query.
2863
+ - Search for code based on a query.
2864
+
2865
+
2866
+ ## Bitbucket
2867
+
2868
+ - Retrieve details about the authenticated user.
2869
+ - Get information about a specific user.
2870
+ - List available workspaces.
2871
+ - List repositories in a workspace.
2872
+ - Get details about a specific repository.
2873
+ - Create a new repository.
2874
+ - Delete an existing repository.
2875
+ - Retrieve contents of a file in a repository.
2876
+ - Upload a file to a repository.
2877
+ - Delete a file from a repository.
2878
+ - List issues in a repository.
2879
+ - Create a new issue.
2880
+ - Comment on an existing issue.
2881
+ - Update details of an issue.
2882
+ - List pull requests in a repository.
2883
+ - Create a new pull request.
2884
+ - Merge an existing pull request.
2885
+ - Search for repositories.
2886
+
2744
2887
 
2745
2888
  # Creating Your Own Plugins
2746
2889
 
@@ -4371,6 +4514,14 @@ may consume additional tokens that are not displayed in the main window.
4371
4514
 
4372
4515
  ## Recent changes:
4373
4516
 
4517
+ **2.6.2 (2025-08-14)**
4518
+
4519
+ - Added plugins (beta): Google, Facebook, X/Twitter, Telegram, Slack, GitHub, Bitbucket.
4520
+
4521
+ **2.6.1 (2025-08-14)**
4522
+
4523
+ - LlamaIndex Agents refactored to Workflows.
4524
+
4374
4525
  **2.6.0 (2025-08-13)**
4375
4526
 
4376
4527
  - Added split responses to the OpenAI Agents in non-streaming mode.