pygpt-net 2.6.3__py3-none-any.whl → 2.6.5__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 (76) hide show
  1. pygpt_net/CHANGELOG.txt +10 -0
  2. pygpt_net/__init__.py +2 -2
  3. pygpt_net/config.py +55 -65
  4. pygpt_net/controller/__init__.py +5 -2
  5. pygpt_net/controller/chat/chat.py +38 -35
  6. pygpt_net/controller/chat/render.py +144 -217
  7. pygpt_net/controller/chat/stream.py +51 -25
  8. pygpt_net/controller/config/config.py +39 -42
  9. pygpt_net/controller/config/field/checkbox.py +16 -12
  10. pygpt_net/controller/config/field/checkbox_list.py +36 -31
  11. pygpt_net/controller/config/field/cmd.py +51 -57
  12. pygpt_net/controller/config/field/combo.py +33 -16
  13. pygpt_net/controller/config/field/dictionary.py +48 -55
  14. pygpt_net/controller/config/field/input.py +50 -32
  15. pygpt_net/controller/config/field/slider.py +40 -45
  16. pygpt_net/controller/config/field/textarea.py +20 -6
  17. pygpt_net/controller/config/placeholder.py +110 -231
  18. pygpt_net/controller/ctx/common.py +48 -49
  19. pygpt_net/controller/ctx/ctx.py +24 -4
  20. pygpt_net/controller/lang/mapping.py +57 -95
  21. pygpt_net/controller/lang/plugins.py +64 -55
  22. pygpt_net/controller/lang/settings.py +39 -38
  23. pygpt_net/controller/layout/layout.py +11 -2
  24. pygpt_net/controller/plugins/plugins.py +19 -1
  25. pygpt_net/controller/settings/profile.py +16 -4
  26. pygpt_net/controller/ui/mode.py +107 -125
  27. pygpt_net/core/bridge/bridge.py +5 -5
  28. pygpt_net/core/command/command.py +149 -219
  29. pygpt_net/core/ctx/ctx.py +94 -146
  30. pygpt_net/core/debug/debug.py +48 -58
  31. pygpt_net/core/models/models.py +74 -112
  32. pygpt_net/core/modes/modes.py +13 -21
  33. pygpt_net/core/plugins/plugins.py +154 -177
  34. pygpt_net/core/presets/presets.py +103 -176
  35. pygpt_net/core/render/web/body.py +2 -3
  36. pygpt_net/core/render/web/renderer.py +109 -180
  37. pygpt_net/core/text/utils.py +28 -44
  38. pygpt_net/core/tokens/tokens.py +104 -203
  39. pygpt_net/data/config/config.json +3 -3
  40. pygpt_net/data/config/models.json +3 -3
  41. pygpt_net/item/ctx.py +141 -139
  42. pygpt_net/plugin/agent/plugin.py +2 -1
  43. pygpt_net/plugin/audio_output/plugin.py +5 -2
  44. pygpt_net/plugin/base/plugin.py +77 -93
  45. pygpt_net/plugin/bitbucket/plugin.py +3 -2
  46. pygpt_net/plugin/cmd_code_interpreter/plugin.py +3 -2
  47. pygpt_net/plugin/cmd_custom/plugin.py +3 -2
  48. pygpt_net/plugin/cmd_files/plugin.py +3 -2
  49. pygpt_net/plugin/cmd_history/plugin.py +3 -2
  50. pygpt_net/plugin/cmd_mouse_control/plugin.py +5 -2
  51. pygpt_net/plugin/cmd_serial/plugin.py +3 -2
  52. pygpt_net/plugin/cmd_system/plugin.py +3 -6
  53. pygpt_net/plugin/cmd_web/plugin.py +3 -2
  54. pygpt_net/plugin/experts/plugin.py +2 -2
  55. pygpt_net/plugin/facebook/plugin.py +3 -4
  56. pygpt_net/plugin/github/plugin.py +4 -2
  57. pygpt_net/plugin/google/plugin.py +3 -3
  58. pygpt_net/plugin/idx_llama_index/plugin.py +3 -2
  59. pygpt_net/plugin/mailer/plugin.py +3 -5
  60. pygpt_net/plugin/openai_vision/plugin.py +3 -2
  61. pygpt_net/plugin/real_time/plugin.py +52 -60
  62. pygpt_net/plugin/slack/plugin.py +3 -4
  63. pygpt_net/plugin/telegram/plugin.py +3 -4
  64. pygpt_net/plugin/twitter/plugin.py +3 -4
  65. pygpt_net/tools/code_interpreter/tool.py +0 -1
  66. pygpt_net/tools/translator/tool.py +1 -1
  67. pygpt_net/ui/layout/ctx/ctx_list.py +10 -6
  68. pygpt_net/ui/main.py +33 -29
  69. pygpt_net/ui/tray.py +61 -60
  70. pygpt_net/ui/widget/lists/context.py +2 -2
  71. pygpt_net/ui/widget/textarea/web.py +18 -14
  72. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.dist-info}/METADATA +12 -2
  73. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.dist-info}/RECORD +76 -76
  74. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.dist-info}/LICENSE +0 -0
  75. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.dist-info}/WHEEL +0 -0
  76. {pygpt_net-2.6.3.dist-info → pygpt_net-2.6.5.dist-info}/entry_points.txt +0 -0
@@ -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.22 00:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.utils import trans
@@ -23,48 +23,49 @@ class Settings:
23
23
 
24
24
  def apply(self):
25
25
  """Apply locale to settings dialog"""
26
- # load settings options if not loaded yet
27
26
  if not self.window.controller.settings.editor.initialized:
28
27
  self.window.controller.settings.editor.load_config_options(False)
29
28
 
30
- # update settings options labels
31
- for id in self.window.controller.settings.editor.options:
32
- option = self.window.controller.settings.editor.options[id]
33
- option_label = 'settings.{}.label'.format(id) # TODO: check
34
- trans_key = '{}'.format(option['label'])
29
+ w = self.window
30
+ tr = trans
31
+ ctrl_settings = w.controller.settings
32
+ editor = ctrl_settings.editor
33
+ options = editor.options
34
+ ui = w.ui
35
+ ui_nodes = ui.nodes
36
+ ui_tabs = ui.tabs
37
+ ui_config = ui.config['config']
35
38
 
36
- # label
37
- if option['type'] == 'bool':
38
- if id in self.window.ui.config['config']:
39
- if hasattr(self.window.ui.config['config'][id], 'setText'):
40
- self.window.ui.config['config'][id].setText(trans(trans_key))
41
- self.window.ui.config['config'][id].box.setText(trans(trans_key))
39
+ for opt_id, option in options.items():
40
+ t_label = tr(option['label'])
41
+ if option.get('type') == 'bool':
42
+ if opt_id in ui_config:
43
+ widget = ui_config[opt_id]
44
+ if hasattr(widget, 'setText'):
45
+ widget.setText(t_label)
46
+ widget.box.setText(t_label)
42
47
  else:
43
- if option_label in self.window.ui.nodes:
44
- self.window.ui.nodes[option_label].setText(trans(trans_key))
48
+ node_key = f'settings.{opt_id}.label'
49
+ node = ui_nodes.get(node_key)
50
+ if node is not None:
51
+ node.setText(t_label)
45
52
 
46
- # description
47
- if 'description' in option \
48
- and option['description'] is not None \
49
- and option['description'].strip() != "":
50
- option_desc = 'settings.{}.desc'.format(id)
51
- if option_desc in self.window.ui.nodes:
52
- trans_desc_key = '{}'.format(option['description'])
53
- self.window.ui.nodes[option_desc].setText(trans(trans_desc_key))
54
- option_desc = option["description"]
55
- if option_desc in self.window.ui.nodes:
56
- trans_desc_key = '{}'.format(option['description'])
57
- self.window.ui.nodes[option_desc].setText(trans(trans_desc_key))
53
+ if 'description' in option and option['description'] is not None and option['description'].strip() != "":
54
+ desc = option['description']
55
+ t_desc = tr(desc)
56
+ node_key1 = f'settings.{opt_id}.desc'
57
+ node1 = ui_nodes.get(node_key1)
58
+ if node1 is not None:
59
+ node1.setText(t_desc)
60
+ node2 = ui_nodes.get(desc)
61
+ if node2 is not None:
62
+ node2.setText(t_desc)
58
63
 
59
- # update sections tabs
60
- sections = self.window.core.settings.get_sections()
61
- i = 0
62
- for section_id in sections.keys():
63
- key = 'settings.section.' + section_id
64
- self.window.ui.tabs['settings.section'].setTabText(i, trans(key))
65
- i += 1
64
+ sections = w.core.settings.get_sections()
65
+ tabs = ui_tabs['settings.section']
66
+ for i, section_id in enumerate(sections.keys()):
67
+ tabs.setTabText(i, tr(f'settings.section.{section_id}'))
66
68
 
67
- # update sections list
68
- idx = self.window.ui.tabs['settings.section'].currentIndex()
69
- self.window.settings.refresh_list()
70
- self.window.controller.settings.set_by_tab(idx)
69
+ idx = tabs.currentIndex()
70
+ w.settings.refresh_list()
71
+ ctrl_settings.set_by_tab(idx)
@@ -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.15 03:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtWidgets import QApplication
@@ -24,7 +24,16 @@ class Layout:
24
24
  """
25
25
  self.window = window
26
26
  # self.splitters = ["main", "main.output", "toolbox", "toolbox.mode", "toolbox.presets"]
27
- self.splitters = ["main", "main.output", "toolbox", "toolbox.mode", "calendar", "interpreter", "interpreter.columns", "columns"]
27
+ self.splitters = [
28
+ "main",
29
+ "main.output",
30
+ "toolbox",
31
+ "toolbox.mode",
32
+ "calendar",
33
+ "interpreter",
34
+ "interpreter.columns",
35
+ "columns",
36
+ ]
28
37
  self.text_nodes = ["input"]
29
38
 
30
39
  def setup(self):
@@ -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.15 03:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import List, Dict, Any
@@ -386,6 +386,24 @@ class Plugins:
386
386
  """
387
387
  return self._apply_cmds_common(Event.CMD_EXECUTE, ctx, cmds, all=all, execute_only=execute_only)
388
388
 
389
+ def apply_cmds_all(
390
+ self,
391
+ ctx: CtxItem,
392
+ cmds: List[Dict[str, Any]]
393
+ ):
394
+ """
395
+ Apply all commands (inline or not)
396
+
397
+ :param ctx: context
398
+ :param cmds: commands
399
+ :return: results
400
+ """
401
+ if self.window.core.config.get("cmd"):
402
+ return self.apply_cmds(ctx, cmds)
403
+ else:
404
+ return self.apply_cmds_inline(ctx, cmds)
405
+
406
+
389
407
  def apply_cmds_inline(
390
408
  self,
391
409
  ctx: CtxItem,
@@ -6,14 +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.18 00:00:00 #
9
+ # Updated Date: 2025.08.16 00:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
13
13
  from pathlib import Path
14
14
  from typing import Optional, Dict, Any
15
15
 
16
- from PySide6.QtCore import Slot
16
+ from PySide6.QtCore import Slot, QTimer
17
17
  from PySide6.QtGui import QAction
18
18
 
19
19
  from pygpt_net.utils import trans
@@ -84,7 +84,7 @@ class Profile:
84
84
  self.window.controller.settings.workdir.update(
85
85
  path,
86
86
  force=True,
87
- profile_name= profile['name']
87
+ profile_name=profile['name']
88
88
  ) # self.after_update() is called in update worker on success
89
89
  else:
90
90
  self.after_update(profile['name'])
@@ -224,7 +224,8 @@ class Profile:
224
224
  uuid = self.window.core.config.profile.add(name, path)
225
225
  self.window.update_status(trans("dialog.profile.status.created"))
226
226
  if self.window.ui.nodes['dialog.profile.checkbox.switch'].isChecked():
227
- self.switch(uuid, force=True)
227
+ QTimer.singleShot(100, lambda: self.after_create(uuid))
228
+ return
228
229
 
229
230
  elif mode == 'edit':
230
231
  # update profile
@@ -284,6 +285,17 @@ class Profile:
284
285
  self.update_menu()
285
286
  self.update_list()
286
287
 
288
+ def after_create(self, uuid: str):
289
+ """
290
+ After profile creation
291
+
292
+ :param uuid: profile UUID
293
+ """
294
+ self.switch(uuid, force=True)
295
+ self.window.ui.dialogs.close('profile.item')
296
+ self.update_menu()
297
+ self.update_list()
298
+
287
299
  def dismiss_update(self):
288
300
  """Dismiss update dialog"""
289
301
  self.window.ui.dialogs.close('profile.item')
@@ -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.15 03:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.core.types import (
@@ -40,154 +40,139 @@ class Mode:
40
40
 
41
41
  mode = self.window.core.config.data['mode']
42
42
 
43
- # presets
44
- if mode != MODE_ASSISTANT:
45
- self.window.ui.nodes['presets.widget'].setVisible(True)
43
+ ui_nodes = self.window.ui.nodes
44
+ ui_tabs = self.window.ui.tabs
45
+ ui_menu = self.window.ui.menu
46
+ ctrl = self.window.controller
47
+ presets_editor = ctrl.presets.editor
48
+
49
+ is_assistant = mode == MODE_ASSISTANT
50
+ is_computer = mode == MODE_COMPUTER
51
+ is_agent = mode == MODE_AGENT
52
+ is_agent_llama = mode == MODE_AGENT_LLAMA
53
+ is_agent_openai = mode == MODE_AGENT_OPENAI
54
+ is_expert = mode == MODE_EXPERT
55
+ is_image = mode == MODE_IMAGE
56
+ is_llama_index = mode == MODE_LLAMA_INDEX
57
+ is_completion = mode == MODE_COMPLETION
58
+
59
+ if not is_assistant:
60
+ ui_nodes['presets.widget'].setVisible(True)
46
61
  else:
47
- self.window.ui.nodes['presets.widget'].setVisible(False)
62
+ ui_nodes['presets.widget'].setVisible(False)
48
63
 
49
- if mode != MODE_COMPUTER:
50
- self.window.ui.nodes['env.widget'].setVisible(False)
64
+ if not is_computer:
65
+ ui_nodes['env.widget'].setVisible(False)
51
66
  else:
52
- self.window.ui.nodes['env.widget'].setVisible(True)
53
-
54
- # presets: labels
55
- if mode == MODE_AGENT:
56
- self.window.ui.nodes['preset.agents.label'].setVisible(True)
57
- self.window.ui.nodes['preset.experts.label'].setVisible(False)
58
- self.window.ui.nodes['preset.presets.label'].setVisible(False)
59
- elif mode == MODE_AGENT_LLAMA:
60
- self.window.ui.nodes['preset.agents.label'].setVisible(True)
61
- self.window.ui.nodes['preset.experts.label'].setVisible(False)
62
- self.window.ui.nodes['preset.presets.label'].setVisible(False)
63
- elif mode == MODE_AGENT_OPENAI:
64
- self.window.ui.nodes['preset.agents.label'].setVisible(True)
65
- self.window.ui.nodes['preset.experts.label'].setVisible(False)
66
- self.window.ui.nodes['preset.presets.label'].setVisible(False)
67
- elif mode == MODE_EXPERT:
68
- self.window.ui.nodes['preset.agents.label'].setVisible(False)
69
- self.window.ui.nodes['preset.experts.label'].setVisible(True)
70
- self.window.ui.nodes['preset.presets.label'].setVisible(False)
67
+ ui_nodes['env.widget'].setVisible(True)
68
+
69
+ show_agents_label = is_agent or is_agent_llama or is_agent_openai
70
+ if show_agents_label:
71
+ ui_nodes['preset.agents.label'].setVisible(True)
72
+ ui_nodes['preset.experts.label'].setVisible(False)
73
+ ui_nodes['preset.presets.label'].setVisible(False)
74
+ elif is_expert:
75
+ ui_nodes['preset.agents.label'].setVisible(False)
76
+ ui_nodes['preset.experts.label'].setVisible(True)
77
+ ui_nodes['preset.presets.label'].setVisible(False)
71
78
  else:
72
- self.window.ui.nodes['preset.agents.label'].setVisible(False)
73
- self.window.ui.nodes['preset.experts.label'].setVisible(False)
74
- self.window.ui.nodes['preset.presets.label'].setVisible(True)
75
-
76
- # presets: experts
77
- if mode == MODE_EXPERT:
78
- self.window.ui.nodes['preset.editor.description'].setVisible(True)
79
- self.window.controller.presets.editor.toggle_tab("remote_tools", True)
79
+ ui_nodes['preset.agents.label'].setVisible(False)
80
+ ui_nodes['preset.experts.label'].setVisible(False)
81
+ ui_nodes['preset.presets.label'].setVisible(True)
82
+
83
+ if is_expert:
84
+ ui_nodes['preset.editor.description'].setVisible(True)
85
+ presets_editor.toggle_tab("remote_tools", True)
80
86
  else:
81
- self.window.controller.presets.editor.toggle_tab("remote_tools", False)
82
- self.window.ui.nodes['preset.editor.description'].setVisible(False)
87
+ presets_editor.toggle_tab("remote_tools", False)
88
+ ui_nodes['preset.editor.description'].setVisible(False)
83
89
 
84
- if mode == MODE_COMPLETION:
85
- self.window.ui.nodes['preset.editor.user_name'].setVisible(True)
90
+ if is_completion:
91
+ ui_nodes['preset.editor.user_name'].setVisible(True)
86
92
  else:
87
- self.window.ui.nodes['preset.editor.user_name'].setVisible(False)
93
+ ui_nodes['preset.editor.user_name'].setVisible(False)
88
94
 
89
- if mode == MODE_AGENT_OPENAI:
90
- self.window.ui.nodes['preset.editor.agent_provider_openai'].setVisible(True)
95
+ if is_agent_openai:
96
+ ui_nodes['preset.editor.agent_provider_openai'].setVisible(True)
91
97
  else:
92
- self.window.ui.nodes['preset.editor.agent_provider_openai'].setVisible(False)
93
-
94
- # presets: editor
95
- if mode == MODE_AGENT:
96
- self.window.controller.presets.editor.toggle_tab("experts", True)
97
- self.window.ui.nodes['preset.editor.temperature'].setVisible(True)
98
- self.window.ui.nodes['preset.editor.idx'].setVisible(False)
99
- self.window.ui.nodes['preset.editor.agent_provider'].setVisible(False)
100
- self.window.ui.nodes['preset.editor.modes'].setVisible(False)
101
- self.window.ui.tabs['preset.editor.extra'].setTabText(0, trans("preset.prompt.agent"))
102
- elif mode == MODE_AGENT_LLAMA:
103
- self.window.controller.presets.editor.toggle_tab("experts", False)
104
- self.window.ui.nodes['preset.editor.temperature'].setVisible(False)
105
- self.window.ui.nodes['preset.editor.idx'].setVisible(True)
106
- self.window.ui.nodes['preset.editor.agent_provider'].setVisible(True)
107
- self.window.ui.nodes['preset.editor.modes'].setVisible(False)
108
- self.window.ui.tabs['preset.editor.extra'].setTabText(0, trans("preset.prompt.agent_llama"))
109
- elif mode == MODE_AGENT_OPENAI:
110
- self.window.controller.presets.editor.toggle_tab("experts", True)
111
- self.window.ui.nodes['preset.editor.temperature'].setVisible(False)
112
- self.window.ui.nodes['preset.editor.idx'].setVisible(True)
113
- self.window.ui.nodes['preset.editor.agent_provider'].setVisible(False)
114
- self.window.ui.nodes['preset.editor.modes'].setVisible(False)
115
- self.window.ui.tabs['preset.editor.extra'].setTabText(0, trans("preset.prompt.agent_llama"))
98
+ ui_nodes['preset.editor.agent_provider_openai'].setVisible(False)
99
+
100
+ if is_agent:
101
+ presets_editor.toggle_tab("experts", True)
102
+ ui_nodes['preset.editor.temperature'].setVisible(True)
103
+ ui_nodes['preset.editor.idx'].setVisible(False)
104
+ ui_nodes['preset.editor.agent_provider'].setVisible(False)
105
+ ui_nodes['preset.editor.modes'].setVisible(False)
106
+ ui_tabs['preset.editor.extra'].setTabText(0, trans("preset.prompt.agent"))
107
+ elif is_agent_llama:
108
+ presets_editor.toggle_tab("experts", False)
109
+ ui_nodes['preset.editor.temperature'].setVisible(False)
110
+ ui_nodes['preset.editor.idx'].setVisible(True)
111
+ ui_nodes['preset.editor.agent_provider'].setVisible(True)
112
+ ui_nodes['preset.editor.modes'].setVisible(False)
113
+ ui_tabs['preset.editor.extra'].setTabText(0, trans("preset.prompt.agent_llama"))
114
+ elif is_agent_openai:
115
+ presets_editor.toggle_tab("experts", True)
116
+ ui_nodes['preset.editor.temperature'].setVisible(False)
117
+ ui_nodes['preset.editor.idx'].setVisible(True)
118
+ ui_nodes['preset.editor.agent_provider'].setVisible(False)
119
+ ui_nodes['preset.editor.modes'].setVisible(False)
120
+ ui_tabs['preset.editor.extra'].setTabText(0, trans("preset.prompt.agent_llama"))
116
121
  else:
117
- if mode == MODE_EXPERT:
118
- self.window.ui.nodes['preset.editor.idx'].setVisible(True)
122
+ if is_expert:
123
+ ui_nodes['preset.editor.idx'].setVisible(True)
119
124
  else:
120
- self.window.ui.nodes['preset.editor.idx'].setVisible(False)
125
+ ui_nodes['preset.editor.idx'].setVisible(False)
121
126
 
122
- self.window.controller.presets.editor.toggle_tab("experts", False)
123
- self.window.ui.nodes['preset.editor.temperature'].setVisible(True)
124
- self.window.ui.nodes['preset.editor.agent_provider'].setVisible(False)
125
- self.window.ui.nodes['preset.editor.modes'].setVisible(True)
126
- self.window.ui.tabs['preset.editor.extra'].setTabText(0, trans("preset.prompt"))
127
+ presets_editor.toggle_tab("experts", False)
128
+ ui_nodes['preset.editor.temperature'].setVisible(True)
129
+ ui_nodes['preset.editor.agent_provider'].setVisible(False)
130
+ ui_nodes['preset.editor.modes'].setVisible(True)
131
+ ui_tabs['preset.editor.extra'].setTabText(0, trans("preset.prompt"))
127
132
 
128
- # img options
129
- if mode == MODE_IMAGE:
130
- self.window.ui.nodes['dalle.options'].setVisible(True)
133
+ if is_image:
134
+ ui_nodes['dalle.options'].setVisible(True)
131
135
  else:
132
- self.window.ui.nodes['dalle.options'].setVisible(False)
136
+ ui_nodes['dalle.options'].setVisible(False)
133
137
 
134
- # agent options
135
- if mode in [MODE_AGENT]:
136
- self.window.ui.nodes['agent.options'].setVisible(True)
138
+ if is_agent:
139
+ ui_nodes['agent.options'].setVisible(True)
137
140
  else:
138
- self.window.ui.nodes['agent.options'].setVisible(False)
141
+ ui_nodes['agent.options'].setVisible(False)
139
142
 
140
- # agent llama options
141
- if mode in [MODE_AGENT_LLAMA, MODE_AGENT_OPENAI]:
142
- self.window.ui.nodes['agent_llama.options'].setVisible(True)
143
+ if is_agent_llama or is_agent_openai:
144
+ ui_nodes['agent_llama.options'].setVisible(True)
143
145
  else:
144
- self.window.ui.nodes['agent_llama.options'].setVisible(False)
146
+ ui_nodes['agent_llama.options'].setVisible(False)
145
147
 
146
- # assistants list
147
- if mode == MODE_ASSISTANT:
148
- self.window.ui.nodes['assistants.widget'].setVisible(True)
148
+ if is_assistant:
149
+ ui_nodes['assistants.widget'].setVisible(True)
149
150
  else:
150
- self.window.ui.nodes['assistants.widget'].setVisible(False)
151
+ ui_nodes['assistants.widget'].setVisible(False)
151
152
 
152
- # indexes list
153
- if mode == MODE_LLAMA_INDEX:
154
- self.window.ui.nodes['idx.options'].setVisible(True)
153
+ if is_llama_index:
154
+ ui_nodes['idx.options'].setVisible(True)
155
155
  else:
156
- self.window.ui.nodes['idx.options'].setVisible(False)
157
-
158
- # stream mode
159
- if mode in [MODE_IMAGE]:
156
+ ui_nodes['idx.options'].setVisible(False)
160
157
 
161
- self.window.ui.nodes['input.stream'].setVisible(False)
158
+ if is_image:
159
+ ui_nodes['input.stream'].setVisible(False)
162
160
  else:
163
- self.window.ui.nodes['input.stream'].setVisible(True)
161
+ ui_nodes['input.stream'].setVisible(True)
164
162
 
165
- # vision
166
163
  show = self.is_vision(mode)
167
- self.window.ui.menu['menu.video'].menuAction().setVisible(show)
168
- self.window.ui.nodes['icon.video.capture'].setVisible(show)
169
- self.window.ui.nodes['attachments.capture_clear'].setVisible(show)
164
+ ui_menu['menu.video'].menuAction().setVisible(show)
165
+ ui_nodes['icon.video.capture'].setVisible(show)
166
+ ui_nodes['attachments.capture_clear'].setVisible(show)
170
167
 
171
- # attachments
172
168
  show = self.are_attachments(mode)
173
- self.window.ui.tabs['input'].setTabVisible(1, show)
169
+ ui_tabs['input'].setTabVisible(1, show)
174
170
 
175
- # uploaded files
176
- if mode == MODE_ASSISTANT:
177
- self.window.ui.tabs['input'].setTabVisible(2, True)
178
- self.window.ui.tabs['input'].setTabVisible(3, False)
179
- else:
180
- if mode != MODE_IMAGE:
181
- self.window.ui.tabs['input'].setTabVisible(2, False)
182
- self.window.ui.tabs['input'].setTabVisible(3, True)
183
- else:
184
- self.window.ui.tabs['input'].setTabVisible(2, False)
185
- self.window.ui.tabs['input'].setTabVisible(3, False)
171
+ ui_tabs['input'].setTabVisible(2, is_assistant)
172
+ ui_tabs['input'].setTabVisible(3, (not is_assistant) and (not is_image))
186
173
 
187
- # show/hide extra options in preset editor
188
- self.window.controller.presets.editor.toggle_extra_options()
174
+ presets_editor.toggle_extra_options()
189
175
 
190
- # chat footer
191
176
  self.toggle_chat_footer()
192
177
 
193
178
  def toggle_chat_footer(self):
@@ -204,13 +189,13 @@ class Mode:
204
189
  :param mode: current mode
205
190
  :return: True if vision is allowed
206
191
  """
207
- if self.window.controller.ui.vision.has_vision():
192
+ ctrl = self.window.controller
193
+ if ctrl.ui.vision.has_vision():
208
194
  return True
209
195
 
210
- if self.window.controller.painter.is_active():
196
+ if ctrl.painter.is_active():
211
197
  return True
212
198
 
213
- # event: UI: vision
214
199
  value = False
215
200
  event = Event(Event.UI_VISION, {
216
201
  'mode': mode,
@@ -226,8 +211,6 @@ class Mode:
226
211
  :param mode: current mode
227
212
  :return: True if attachments are allowed
228
213
  """
229
- # event: UI: attachments
230
- # value = False
231
214
  event = Event(Event.UI_ATTACHMENTS, {
232
215
  'mode': mode,
233
216
  'value': True,
@@ -241,5 +224,4 @@ class Mode:
241
224
 
242
225
  def hide_chat_footer(self):
243
226
  """Hide chat footer"""
244
- self.window.ui.nodes['chat.footer'].setVisible(False)
245
-
227
+ self.window.ui.nodes['chat.footer'].setVisible(False)
@@ -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.05 21:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import time
@@ -39,10 +39,10 @@ class Bridge:
39
39
  self.last_call = None # last API call time, for throttling
40
40
  self.last_context = None # last context
41
41
  self.last_context_quick = None # last context for quick call
42
- self.sync_modes = [
42
+ self.sync_modes = (
43
43
  MODE_ASSISTANT,
44
44
  MODE_EXPERT,
45
- ]
45
+ )
46
46
  self.worker = None
47
47
 
48
48
  def request(
@@ -59,7 +59,7 @@ class Bridge:
59
59
  if self.window.controller.kernel.stopped():
60
60
  return False
61
61
 
62
- allowed_model_change = [MODE_VISION]
62
+ allowed_model_change = MODE_VISION
63
63
  is_virtual = False
64
64
  force_sync = False
65
65
 
@@ -81,7 +81,7 @@ class Bridge:
81
81
  context.parent_mode = base_mode # store base mode
82
82
 
83
83
  # get agent or expert internal sub-mode
84
- if base_mode in [MODE_AGENT, MODE_EXPERT]:
84
+ if base_mode in (MODE_AGENT, MODE_EXPERT):
85
85
  is_virtual = True
86
86
  sub_mode = None # inline switch to sub-mode, because agent is a virtual mode only
87
87
  if base_mode == MODE_AGENT: