pygpt-net 2.4.55__py3-none-any.whl → 2.4.57__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 (67) hide show
  1. CHANGELOG.md +9 -0
  2. README.md +10 -1
  3. pygpt_net/CHANGELOG.txt +9 -0
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/controller/access/__init__.py +1 -3
  6. pygpt_net/controller/access/voice.py +20 -7
  7. pygpt_net/controller/{attachment.py → attachment/__init__.py} +0 -0
  8. pygpt_net/controller/{camera.py → camera/__init__.py} +1 -1
  9. pygpt_net/controller/{files.py → files/__init__.py} +0 -0
  10. pygpt_net/controller/{finder.py → finder/__init__.py} +0 -0
  11. pygpt_net/controller/{launcher.py → launcher/__init__.py} +0 -0
  12. pygpt_net/controller/{layout.py → layout/__init__.py} +0 -0
  13. pygpt_net/controller/{notepad.py → notepad/__init__.py} +0 -0
  14. pygpt_net/controller/settings/editor.py +4 -0
  15. pygpt_net/core/access/shortcuts.py +48 -29
  16. pygpt_net/core/{camera.py → camera/__init__.py} +5 -4
  17. pygpt_net/core/{command.py → command/__init__.py} +4 -3
  18. pygpt_net/core/{dispatcher.py → dispatcher/__init__.py} +0 -0
  19. pygpt_net/core/{history.py → history/__init__.py} +0 -2
  20. pygpt_net/core/{image.py → image/__init__.py} +0 -0
  21. pygpt_net/core/{info.py → info/__init__.py} +0 -0
  22. pygpt_net/core/{locale.py → locale/__init__.py} +0 -0
  23. pygpt_net/core/{notepad.py → notepad/__init__.py} +0 -0
  24. pygpt_net/core/{platforms.py → platforms/__init__.py} +0 -0
  25. pygpt_net/core/{plugins.py → plugins/__init__.py} +0 -0
  26. pygpt_net/core/{settings.py → settings/__init__.py} +0 -0
  27. pygpt_net/core/tabs/__init__.py +8 -6
  28. pygpt_net/core/{tokens.py → tokens/__init__.py} +0 -0
  29. pygpt_net/data/config/config.json +9 -9
  30. pygpt_net/data/config/models.json +3 -3
  31. pygpt_net/data/config/modes.json +3 -3
  32. pygpt_net/launcher.py +3 -2
  33. pygpt_net/plugin/audio_input/simple.py +2 -3
  34. pygpt_net/plugin/audio_input/worker.py +1 -1
  35. pygpt_net/provider/core/config/patch.py +13 -1
  36. pygpt_net/tools/code_interpreter/__init__.py +2 -1
  37. pygpt_net/tools/code_interpreter/ui/dialogs.py +10 -1
  38. pygpt_net/tools/code_interpreter/ui/widgets.py +56 -1
  39. pygpt_net/tools/html_canvas/__init__.py +2 -1
  40. pygpt_net/tools/html_canvas/ui/dialogs.py +10 -1
  41. pygpt_net/tools/html_canvas/ui/widgets.py +33 -1
  42. pygpt_net/ui/__init__.py +1 -1
  43. pygpt_net/ui/layout/chat/calendar.py +5 -2
  44. pygpt_net/ui/layout/chat/explorer.py +4 -2
  45. pygpt_net/ui/layout/chat/painter.py +4 -2
  46. pygpt_net/ui/main.py +62 -2
  47. pygpt_net/ui/widget/calendar/select.py +29 -1
  48. pygpt_net/ui/widget/draw/painter.py +25 -1
  49. pygpt_net/ui/widget/filesystem/explorer.py +24 -1
  50. pygpt_net/ui/widget/tabs/body.py +54 -4
  51. pygpt_net/ui/widget/textarea/calendar_note.py +26 -2
  52. pygpt_net/ui/widget/textarea/html.py +21 -2
  53. pygpt_net/ui/widget/textarea/notepad.py +37 -3
  54. pygpt_net/ui/widget/textarea/web.py +4 -2
  55. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.57.dist-info}/METADATA +11 -2
  56. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.57.dist-info}/RECORD +67 -67
  57. /pygpt_net/controller/{command.py → command/__init__.py} +0 -0
  58. /pygpt_net/controller/{mode.py → mode/__init__.py} +0 -0
  59. /pygpt_net/core/{installer.py → installer/__init__.py} +0 -0
  60. /pygpt_net/core/{models.py → models/__init__.py} +0 -0
  61. /pygpt_net/core/{modes.py → modes/__init__.py} +0 -0
  62. /pygpt_net/core/{presets.py → presets/__init__.py} +0 -0
  63. /pygpt_net/core/{profile.py → profile/__init__.py} +0 -0
  64. /pygpt_net/core/{worker.py → worker/__init__.py} +0 -0
  65. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.57.dist-info}/LICENSE +0 -0
  66. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.57.dist-info}/WHEEL +0 -0
  67. {pygpt_net-2.4.55.dist-info → pygpt_net-2.4.57.dist-info}/entry_points.txt +0 -0
CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 2.4.57 (2025-01-19)
4
+
5
+ - Logging fix.
6
+
7
+ ## 2.4.56 (2025-01-19)
8
+
9
+ - Improved tab switching and focus change.
10
+ - Improved global keyboard shortcuts handling.
11
+
3
12
  ## 2.4.55 (2025-01-18)
4
13
 
5
14
  - Added a new option in settings: Audio -> Recording timeout.
README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![pygpt](https://snapcraft.io/pygpt/badge.svg)](https://snapcraft.io/pygpt)
4
4
 
5
- Release: **2.4.55** | build: **2025.01.18** | Python: **>=3.10, <3.13**
5
+ Release: **2.4.57** | build: **2025.01.19** | Python: **>=3.10, <3.13**
6
6
 
7
7
  > Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
8
8
  >
@@ -3960,6 +3960,15 @@ may consume additional tokens that are not displayed in the main window.
3960
3960
 
3961
3961
  ## Recent changes:
3962
3962
 
3963
+ **2.4.57 (2025-01-19)**
3964
+
3965
+ - Logging fix.
3966
+
3967
+ **2.4.56 (2025-01-19)**
3968
+
3969
+ - Improved tab switching and focus change.
3970
+ - Improved global keyboard shortcuts handling.
3971
+
3963
3972
  **2.4.55 (2025-01-18)**
3964
3973
 
3965
3974
  - Added a new option in settings: Audio -> Recording timeout.
pygpt_net/CHANGELOG.txt CHANGED
@@ -1,3 +1,12 @@
1
+ 2.4.57 (2025-01-19)
2
+
3
+ - Logging fix.
4
+
5
+ 2.4.56 (2025-01-19)
6
+
7
+ - Improved tab switching and focus change.
8
+ - Improved global keyboard shortcuts handling.
9
+
1
10
  2.4.55 (2025-01-18)
2
11
 
3
12
  - Added a new option in settings: Audio -> Recording timeout.
pygpt_net/__init__.py CHANGED
@@ -6,15 +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.01.18 16:00:00 #
9
+ # Updated Date: 2025.01.19 16:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  __author__ = "Marcin Szczygliński"
13
13
  __copyright__ = "Copyright 2025, Marcin Szczygliński"
14
14
  __credits__ = ["Marcin Szczygliński"]
15
15
  __license__ = "MIT"
16
- __version__ = "2.4.55"
17
- __build__ = "2025.01.18"
16
+ __version__ = "2.4.57"
17
+ __build__ = "2025.01.19"
18
18
  __maintainer__ = "Marcin Szczygliński"
19
19
  __github__ = "https://github.com/szczyglis-dev/py-gpt"
20
20
  __report__ = "https://github.com/szczyglis-dev/py-gpt/issues"
@@ -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.26 19:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from pygpt_net.core.events import BaseEvent, ControlEvent, AppEvent
@@ -73,9 +73,7 @@ class Access:
73
73
  self.window.core.plugins.get("audio_input").handler_simple.stop_recording(timeout=True)
74
74
 
75
75
  # stop audio output if playing
76
- #if self.window.controller.audio.is_playing():
77
76
  self.window.controller.audio.stop_output()
78
77
 
79
78
  # stop generating if active
80
- #if self.window.controller.chat.input.generating:
81
79
  self.window.controller.kernel.stop()
@@ -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.01.16 17:00:00 #
9
+ # Updated Date: 2025.01.18 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, List, Dict, Any
@@ -24,7 +24,6 @@ from pygpt_net.utils import trans
24
24
 
25
25
  class Voice:
26
26
 
27
- TIMEOUT_SECONDS = 120 # 2 minutes, max recording time before timeout
28
27
  MIN_FRAMES = 25 # minimum frames to start transcription
29
28
  PLAY_DELAY = 500 # ms, delay before playing audio event
30
29
 
@@ -213,6 +212,18 @@ class Voice:
213
212
 
214
213
  def start_recording(self):
215
214
  """Start recording"""
215
+ # display snap warning if not displayed yet
216
+ if (not self.window.core.config.get("audio.input.snap", False)
217
+ or not self.window.core.config.has("audio.input.snap")):
218
+ if self.window.core.platforms.is_snap():
219
+ self.window.ui.dialogs.open(
220
+ 'snap_audio_input',
221
+ width=400,
222
+ height=200
223
+ )
224
+ self.window.core.config.set("audio.input.snap", True)
225
+ self.window.core.config.save()
226
+ return
216
227
  try:
217
228
  self.is_recording = True
218
229
  self.switch_btn_stop()
@@ -227,10 +238,12 @@ class Voice:
227
238
  )
228
239
 
229
240
  # start timeout timer to prevent infinite recording
230
- if self.timer is None:
231
- self.timer = QTimer()
232
- self.timer.timeout.connect(self.stop_timeout)
233
- self.timer.start(self.TIMEOUT_SECONDS * 1000)
241
+ timeout = int(self.window.core.config.get('audio.input.timeout', 120) or 0) # get timeout
242
+ if timeout > 0:
243
+ if self.timer is None:
244
+ self.timer = QTimer()
245
+ self.timer.timeout.connect(self.stop_timeout)
246
+ self.timer.start(timeout * 1000)
234
247
 
235
248
  if not self.window.core.audio.capture.check_audio_input():
236
249
  raise Exception("Audio input not working.")
@@ -273,7 +286,7 @@ class Voice:
273
286
  # abort if timeout
274
287
  if timeout:
275
288
  self.window.dispatch(AppEvent(AppEvent.VOICE_CONTROL_STOPPED)) # app event
276
- self.window.update_status("Aborted.".format(self.TIMEOUT_SECONDS))
289
+ self.window.update_status("Aborted.".format(timeout))
277
290
  return
278
291
 
279
292
  if self.window.core.audio.capture.has_frames():
@@ -227,7 +227,7 @@ class Camera(QObject):
227
227
 
228
228
  def capture_frame_save(self) -> str:
229
229
  """
230
- Capture frame and save
230
+ Capture frame and save
231
231
 
232
232
  :return: Path to saved frame
233
233
  """
File without changes
File without changes
File without changes
File without changes
@@ -199,6 +199,10 @@ class Editor:
199
199
  if self.config_changed('ctx.sources') or self.config_changed('ctx.audio'):
200
200
  self.window.controller.ctx.refresh()
201
201
 
202
+ # update global shortcuts
203
+ if self.config_changed('access.shortcuts'):
204
+ self.window.setup_global_shortcuts()
205
+
202
206
  self.before_config = copy.deepcopy(self.window.core.config.all())
203
207
  self.window.controller.settings.close_window(id)
204
208
 
@@ -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.14 08:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import copy
@@ -52,11 +52,52 @@ class Shortcuts:
52
52
  """
53
53
  # SHIFT not working properly
54
54
  modifiers_names = [
55
- '---', 'Control', 'Alt', 'Meta', 'Keypad', 'GroupSwitch',
55
+ '---', 'Ctrl', 'Alt', 'Shift',
56
56
  ]
57
57
  modifiers = [{name: name} for name in modifiers_names]
58
58
  return modifiers
59
59
 
60
+ def handle_global_shortcuts(self, event: QEvent):
61
+ """
62
+ Handle global shortcuts
63
+
64
+ :param event: event
65
+ """
66
+ # esc key
67
+ if event.type() == QEvent.KeyPress and event.key() == QtCore.Qt.Key_Escape:
68
+ self.window.controller.access.on_escape()
69
+ return True
70
+
71
+ if not hasattr(self.window, 'core') or not hasattr(self.window.core, 'config'):
72
+ return False
73
+
74
+ if event.type() == QEvent.KeyPress:
75
+ # shortcuts
76
+ config = copy.deepcopy(self.window.core.config.get("access.shortcuts"))
77
+ for shortcut in config:
78
+ if shortcut['key'] == "" or shortcut['key'] is None:
79
+ continue
80
+ key_name = 'Key_' + str(shortcut['key'])
81
+ if hasattr(QtCore.Qt, key_name):
82
+ shortcut['key'] = getattr(QtCore.Qt, 'Key_' + str(shortcut['key']))
83
+ else:
84
+ continue
85
+ modifier_name = str(shortcut['key_modifier']) + 'Modifier'
86
+ if shortcut['key_modifier'] == "" or shortcut['key_modifier'] is None or shortcut[
87
+ 'key_modifier'] == "---":
88
+ shortcut['key_modifier'] = QtCore.Qt.NoModifier
89
+ elif hasattr(QtCore.Qt, modifier_name):
90
+ shortcut['key_modifier'] = getattr(QtCore.Qt, modifier_name, QtCore.Qt.NoModifier)
91
+
92
+ for shortcut in config:
93
+ if (event.key() == shortcut['key'] and
94
+ (shortcut['key_modifier'] == QtCore.Qt.NoModifier or event.modifiers() == shortcut[
95
+ 'key_modifier'])
96
+ ):
97
+ self.window.dispatch(ControlEvent(shortcut['action']))
98
+ return True
99
+ return False
100
+
60
101
 
61
102
  class GlobalShortcutFilter(QObject):
62
103
  def __init__(self, window=None):
@@ -72,33 +113,11 @@ class GlobalShortcutFilter(QObject):
72
113
  :return: True if event was handled
73
114
  """
74
115
  try:
75
- # esc key
76
- if event.type() == QEvent.KeyPress and event.key() == QtCore.Qt.Key_Escape:
77
- self.window.controller.access.on_escape()
78
-
79
- if event.type() == QEvent.KeyPress:
80
- # shortcuts
81
- config = copy.deepcopy(self.window.core.config.get("access.shortcuts"))
82
- for shortcut in config:
83
- if shortcut['key'] == "" or shortcut['key'] is None:
84
- continue
85
- key_name = 'Key_' + str(shortcut['key'])
86
- if hasattr(QtCore.Qt, key_name):
87
- shortcut['key'] = getattr(QtCore.Qt, 'Key_' + str(shortcut['key']))
88
- else:
89
- continue
90
- modifier_name = str(shortcut['key_modifier']) + 'Modifier'
91
- if shortcut['key_modifier'] == "" or shortcut['key_modifier'] is None or shortcut['key_modifier'] == "---":
92
- shortcut['key_modifier'] = QtCore.Qt.NoModifier
93
- elif hasattr(QtCore.Qt, modifier_name):
94
- shortcut['key_modifier'] = getattr(QtCore.Qt, modifier_name, QtCore.Qt.NoModifier)
95
-
96
- for shortcut in config:
97
- if (event.key() == shortcut['key'] and
98
- (shortcut['key_modifier'] == QtCore.Qt.NoModifier or event.modifiers() == shortcut['key_modifier'])
99
- ):
100
- self.window.dispatch(ControlEvent(shortcut['action']))
101
- return True
116
+ if event.type() != QEvent.KeyPress:
117
+ return False
118
+ if not self.window or not hasattr(self.window, 'controller'):
119
+ return False
120
+ return self.window.core.access.shortcuts.handle_global_shortcuts(event)
102
121
  except Exception as e:
103
122
  print(e)
104
123
  return False
@@ -68,9 +68,10 @@ class CaptureWorker(QRunnable):
68
68
  self.capture.set(cv2.CAP_PROP_FRAME_WIDTH, self.window.core.config.get('vision.capture.width'))
69
69
  self.capture.set(cv2.CAP_PROP_FRAME_HEIGHT, self.window.core.config.get('vision.capture.height'))
70
70
  except Exception as e:
71
- self.signals.error.emit(e)
72
- print("Camera thread setup exception", e)
73
- self.signals.finished.emit(e)
71
+ self.window.core.debug.log(e)
72
+ if self.signals is not None:
73
+ self.signals.error.emit(e)
74
+ self.signals.finished.emit(e)
74
75
 
75
76
  @Slot()
76
77
  def run(self):
@@ -99,9 +100,9 @@ class CaptureWorker(QRunnable):
99
100
  self.signals.capture.emit(frame)
100
101
  last_frame_time = now
101
102
  except Exception as e:
103
+ self.window.core.debug.log(e)
102
104
  if self.signals is not None:
103
105
  self.signals.error.emit(e)
104
- print("Camera thread capture exception", e)
105
106
 
106
107
  # release camera
107
108
  self.release()
@@ -104,7 +104,8 @@ class Command:
104
104
 
105
105
  # remove description and move to help
106
106
  if "description" in data[cmd_name]["params"][key]:
107
- data[cmd_name]["params"][key]["help"] = data[cmd_name]["params"][key]["description"]
107
+ data[cmd_name]["params"][key]["help"] = data[cmd_name]["params"][key][
108
+ "description"]
108
109
  del data[cmd_name]["params"][key]["description"]
109
110
 
110
111
  except Exception as e:
@@ -397,7 +398,7 @@ class Command:
397
398
  ) -> List[Dict[str, Any]]:
398
399
  """
399
400
  Convert internal functions to native API format
400
-
401
+
401
402
  :param: all True to include all
402
403
  :param: parent_id: parent context ID
403
404
  :return: native functions list
@@ -406,7 +407,7 @@ class Command:
406
407
  # Native API format (example):
407
408
  # https://platform.openai.com/docs/guides/function-calling
408
409
  # At this moment it must be converted to format:
409
-
410
+
410
411
  functions = [
411
412
  {
412
413
  "name": "get_delivery_date",
File without changes
@@ -92,5 +92,3 @@ class History:
92
92
  f.write(content.strip() + "\n")
93
93
  except Exception as e:
94
94
  print(e)
95
-
96
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -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.14 08:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import uuid
@@ -448,7 +448,7 @@ class Tabs:
448
448
  column = self.window.ui.layout.get_column_by_idx(tab.column_idx)
449
449
  tabs = column.get_tabs()
450
450
  tab.parent = column
451
- tab.child = self.window.core.ctx.container.get(tab)
451
+ tab.child = self.window.core.ctx.container.get(tab) # tab is already appended here
452
452
  if tab.new_idx is not None:
453
453
  tab.idx = tabs.insertTab(tab.new_idx, tab.child, tab.title)
454
454
  else:
@@ -508,6 +508,7 @@ class Tabs:
508
508
  tabs = column.get_tabs()
509
509
  tab.parent = column
510
510
  tab.child = self.window.ui.chat.output.painter.setup()
511
+ tab.child.append(self.window.ui.painter)
511
512
  tab.idx = tabs.addTab(tab.child, tab.title)
512
513
  tab.child.setOwner(tab)
513
514
  tabs.setTabIcon(tab.idx, QIcon(tab.icon))
@@ -805,9 +806,10 @@ class Tabs:
805
806
  layout = QVBoxLayout()
806
807
  layout.addWidget(widget)
807
808
  layout.setContentsMargins(0, 0, 0, 0)
808
- widget = TabBody()
809
- widget.setLayout(layout)
810
- return widget
809
+ tab_widget = TabBody(self.window)
810
+ tab_widget.append(widget)
811
+ tab_widget.setLayout(layout)
812
+ return tab_widget
811
813
 
812
814
  def from_layout(self, layout: QLayout) -> TabBody:
813
815
  """
@@ -817,6 +819,6 @@ class Tabs:
817
819
  :return: TabBody
818
820
  """
819
821
  layout.setContentsMargins(0, 0, 0, 0)
820
- widget = TabBody()
822
+ widget = TabBody(self.window)
821
823
  widget.setLayout(layout)
822
824
  return widget
File without changes
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.4.55",
4
- "app.version": "2.4.55",
5
- "updated_at": "2025-01-18T00:00:00"
3
+ "version": "2.4.57",
4
+ "app.version": "2.4.57",
5
+ "updated_at": "2025-01-19T00:00:00"
6
6
  },
7
7
  "access.audio.event.speech": false,
8
8
  "access.audio.event.speech.disabled": [],
@@ -13,32 +13,32 @@
13
13
  {
14
14
  "action": "voice_cmd.toggle",
15
15
  "key": "Space",
16
- "key_modifier": "Control"
16
+ "key_modifier": "Ctrl"
17
17
  },
18
18
  {
19
19
  "action": "tab.chat",
20
20
  "key": "1",
21
- "key_modifier": "Control"
21
+ "key_modifier": "Ctrl"
22
22
  },
23
23
  {
24
24
  "action": "tab.files",
25
25
  "key": "2",
26
- "key_modifier": "Control"
26
+ "key_modifier": "Ctrl"
27
27
  },
28
28
  {
29
29
  "action": "tab.calendar",
30
30
  "key": "3",
31
- "key_modifier": "Control"
31
+ "key_modifier": "Ctrl"
32
32
  },
33
33
  {
34
34
  "action": "tab.draw",
35
35
  "key": "4",
36
- "key_modifier": "Control"
36
+ "key_modifier": "Ctrl"
37
37
  },
38
38
  {
39
39
  "action": "tab.notepad",
40
40
  "key": "5",
41
- "key_modifier": "Control"
41
+ "key_modifier": "Ctrl"
42
42
  }
43
43
  ],
44
44
  "access.voice_control": false,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.4.55",
4
- "app.version": "2.4.55",
5
- "updated_at": "2025-01-18T00:00:00"
3
+ "version": "2.4.57",
4
+ "app.version": "2.4.57",
5
+ "updated_at": "2025-01-19T00:00:00"
6
6
  },
7
7
  "items": {
8
8
  "claude-3-5-sonnet-20240620": {
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.4.55",
4
- "app.version": "2.4.55",
5
- "updated_at": "2025-01-18T00:00:00"
3
+ "version": "2.4.57",
4
+ "app.version": "2.4.57",
5
+ "updated_at": "2025-01-19T00:00:00"
6
6
  },
7
7
  "items": {
8
8
  "chat": {
pygpt_net/launcher.py CHANGED
@@ -6,8 +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: 2024.11.20 21:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
+
11
12
  import os
12
13
  import sys
13
14
  import argparse
@@ -266,5 +267,5 @@ class Launcher:
266
267
  self.window.ui.tray.setup(self.app)
267
268
  self.window.controller.after_setup()
268
269
  self.window.dispatch(AppEvent(AppEvent.APP_STARTED)) # app event
269
- self.window.installEventFilter(self.shortcut_filter)
270
+ self.window.setup_global_shortcuts()
270
271
  sys.exit(self.app.exec())
@@ -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.01.18 16:00:00 #
9
+ # Updated Date: 2025.01.18 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -20,7 +20,6 @@ from pygpt_net.utils import trans
20
20
 
21
21
  class Simple:
22
22
 
23
- TIMEOUT_SECONDS = 120 # 2 minutes, max recording time before timeout
24
23
  MIN_FRAMES = 25 # minimum frames to start transcription
25
24
 
26
25
  def __init__(self, plugin=None):
@@ -145,7 +144,7 @@ class Simple:
145
144
  self.plugin.window.core.audio.capture.stop() # stop recording
146
145
  # abort if timeout
147
146
  if timeout:
148
- self.plugin.window.update_status("Aborted.".format(self.TIMEOUT_SECONDS))
147
+ self.plugin.window.update_status("Aborted.".format(timeout))
149
148
  return
150
149
 
151
150
  if self.plugin.window.core.audio.capture.has_frames():
@@ -16,7 +16,7 @@ import audioop
16
16
 
17
17
  from PySide6.QtCore import Slot, Signal
18
18
 
19
- from pygpt_net.core.tabs import Tab
19
+ from pygpt_net.core.tabs.tab import Tab
20
20
  from pygpt_net.utils import trans
21
21
  from pygpt_net.plugin.base.worker import BaseWorker, BaseSignals
22
22
 
@@ -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.01.18 16:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import copy
@@ -1819,6 +1819,18 @@ class Patch:
1819
1819
  if 'audio.input.timeout.continuous' not in data:
1820
1820
  data["audio.input.timeout.continuous"] = False
1821
1821
 
1822
+ # < 2.4.56
1823
+ if old < parse_version("2.4.56"):
1824
+ print("Migrating config from < 2.4.56...")
1825
+ remove_modifiers = ["Meta", "Keypad", "GroupSwitch"]
1826
+ if 'access.shortcuts' in data:
1827
+ for item in data['access.shortcuts']:
1828
+ if 'key_modifier' in item and item['key_modifier'] == 'Control':
1829
+ item['key_modifier'] = 'Ctrl'
1830
+ elif 'key_modifier' in item and item['key_modifier'] in remove_modifiers:
1831
+ item['key_modifier'] = ''
1832
+ updated = True
1833
+
1822
1834
  # update file
1823
1835
  migrated = False
1824
1836
  if updated:
@@ -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.14 22:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import os
@@ -539,6 +539,7 @@ class CodeInterpreter(BaseTool):
539
539
  widget.setLayout(layout)
540
540
  self.load_history()
541
541
  self.load_output()
542
+ tool.set_tab(tab)
542
543
  return widget
543
544
 
544
545
  def setup_dialogs(self):
@@ -6,13 +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: 2024.12.12 01:00:00 #
9
+ # Updated Date: 2025.01.19 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt
13
13
  from PySide6.QtGui import QAction, QIcon
14
14
  from PySide6.QtWidgets import QMenuBar
15
15
 
16
+ from pygpt_net.core.tabs.tab import Tab
16
17
  from pygpt_net.tools.code_interpreter.ui.widgets import ToolWidget
17
18
  from pygpt_net.ui.widget.dialog.base import BaseDialog
18
19
  from pygpt_net.utils import trans
@@ -33,6 +34,14 @@ class Tool:
33
34
  self.menu = {}
34
35
  self.actions = {} # menu actions
35
36
 
37
+ def set_tab(self, tab: Tab):
38
+ """
39
+ Set tab
40
+
41
+ :param tab: Tab
42
+ """
43
+ self.widget.set_tab(tab)
44
+
36
45
  def setup_menu(self) -> QMenuBar:
37
46
  """
38
47
  Setup dialog menu