pygpt-net 2.4.28__py3-none-any.whl → 2.4.34__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 (168) hide show
  1. CHANGELOG.md +40 -0
  2. README.md +62 -5
  3. pygpt_net/CHANGELOG.txt +40 -0
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/controller/access/__init__.py +5 -5
  6. pygpt_net/controller/access/control.py +3 -2
  7. pygpt_net/controller/attachment.py +67 -1
  8. pygpt_net/controller/audio/__init__.py +34 -6
  9. pygpt_net/controller/chat/__init__.py +3 -1
  10. pygpt_net/controller/chat/attachment.py +239 -37
  11. pygpt_net/controller/chat/audio.py +99 -0
  12. pygpt_net/controller/chat/input.py +10 -3
  13. pygpt_net/controller/chat/output.py +4 -1
  14. pygpt_net/controller/chat/text.py +10 -5
  15. pygpt_net/controller/dialogs/confirm.py +17 -1
  16. pygpt_net/controller/kernel/reply.py +5 -8
  17. pygpt_net/controller/lang/custom.py +3 -1
  18. pygpt_net/controller/mode.py +2 -1
  19. pygpt_net/controller/presets/editor.py +11 -2
  20. pygpt_net/core/access/voice.py +2 -2
  21. pygpt_net/core/agents/legacy.py +3 -1
  22. pygpt_net/core/attachments/__init__.py +11 -7
  23. pygpt_net/core/attachments/context.py +226 -44
  24. pygpt_net/core/{audio.py → audio/__init__.py} +1 -1
  25. pygpt_net/core/audio/context.py +34 -0
  26. pygpt_net/core/bridge/context.py +29 -1
  27. pygpt_net/core/bridge/worker.py +16 -1
  28. pygpt_net/core/ctx/__init__.py +4 -1
  29. pygpt_net/core/db/__init__.py +4 -2
  30. pygpt_net/core/debug/attachments.py +3 -1
  31. pygpt_net/core/debug/context.py +5 -1
  32. pygpt_net/core/debug/presets.py +3 -1
  33. pygpt_net/core/docker/__init__.py +170 -16
  34. pygpt_net/core/docker/builder.py +6 -2
  35. pygpt_net/core/events/event.py +3 -1
  36. pygpt_net/core/experts/__init__.py +24 -6
  37. pygpt_net/core/idx/chat.py +55 -4
  38. pygpt_net/core/idx/indexing.py +123 -15
  39. pygpt_net/core/modes.py +3 -1
  40. pygpt_net/core/presets.py +13 -2
  41. pygpt_net/core/render/markdown/pid.py +2 -1
  42. pygpt_net/core/render/plain/pid.py +2 -1
  43. pygpt_net/core/render/web/body.py +34 -12
  44. pygpt_net/core/render/web/pid.py +2 -1
  45. pygpt_net/core/render/web/renderer.py +12 -3
  46. pygpt_net/core/tokens.py +4 -2
  47. pygpt_net/core/types/mode.py +2 -1
  48. pygpt_net/data/config/config.json +7 -4
  49. pygpt_net/data/config/models.json +191 -6
  50. pygpt_net/data/config/modes.json +11 -5
  51. pygpt_net/data/config/presets/current.audio.json +34 -0
  52. pygpt_net/data/config/settings.json +15 -1
  53. pygpt_net/data/css/web.css +70 -0
  54. pygpt_net/data/css/web.dark.css +4 -1
  55. pygpt_net/data/css/web.light.css +1 -1
  56. pygpt_net/data/locale/locale.de.ini +33 -20
  57. pygpt_net/data/locale/locale.en.ini +73 -58
  58. pygpt_net/data/locale/locale.es.ini +33 -20
  59. pygpt_net/data/locale/locale.fr.ini +35 -22
  60. pygpt_net/data/locale/locale.it.ini +33 -20
  61. pygpt_net/data/locale/locale.pl.ini +36 -23
  62. pygpt_net/data/locale/locale.uk.ini +33 -20
  63. pygpt_net/data/locale/locale.zh.ini +40 -27
  64. pygpt_net/data/locale/plugin.cmd_code_interpreter.de.ini +6 -0
  65. pygpt_net/data/locale/plugin.cmd_code_interpreter.en.ini +15 -7
  66. pygpt_net/data/locale/plugin.cmd_code_interpreter.es.ini +6 -0
  67. pygpt_net/data/locale/plugin.cmd_code_interpreter.fr.ini +6 -0
  68. pygpt_net/data/locale/plugin.cmd_code_interpreter.it.ini +6 -0
  69. pygpt_net/data/locale/plugin.cmd_code_interpreter.pl.ini +6 -0
  70. pygpt_net/data/locale/plugin.cmd_code_interpreter.uk.ini +6 -0
  71. pygpt_net/data/locale/plugin.cmd_code_interpreter.zh.ini +6 -0
  72. pygpt_net/data/locale/plugin.cmd_files.de.ini +4 -4
  73. pygpt_net/data/locale/plugin.cmd_files.en.ini +4 -4
  74. pygpt_net/data/locale/plugin.cmd_files.es.ini +4 -4
  75. pygpt_net/data/locale/plugin.cmd_files.fr.ini +4 -4
  76. pygpt_net/data/locale/plugin.cmd_files.it.ini +4 -4
  77. pygpt_net/data/locale/plugin.cmd_files.pl.ini +4 -4
  78. pygpt_net/data/locale/plugin.cmd_files.uk.ini +4 -4
  79. pygpt_net/data/locale/plugin.cmd_files.zh.ini +4 -4
  80. pygpt_net/data/locale/plugin.cmd_system.de.ini +6 -6
  81. pygpt_net/data/locale/plugin.cmd_system.en.ini +12 -6
  82. pygpt_net/data/locale/plugin.cmd_system.es.ini +6 -6
  83. pygpt_net/data/locale/plugin.cmd_system.fr.ini +6 -6
  84. pygpt_net/data/locale/plugin.cmd_system.it.ini +6 -6
  85. pygpt_net/data/locale/plugin.cmd_system.pl.ini +6 -6
  86. pygpt_net/data/locale/plugin.cmd_system.uk.ini +6 -6
  87. pygpt_net/data/locale/plugin.cmd_system.zh.ini +6 -6
  88. pygpt_net/data/locale/plugin.cmd_web.de.ini +5 -5
  89. pygpt_net/data/locale/plugin.cmd_web.en.ini +5 -5
  90. pygpt_net/data/locale/plugin.cmd_web.es.ini +5 -5
  91. pygpt_net/data/locale/plugin.cmd_web.fr.ini +5 -5
  92. pygpt_net/data/locale/plugin.cmd_web.it.ini +5 -5
  93. pygpt_net/data/locale/plugin.cmd_web.pl.ini +5 -5
  94. pygpt_net/data/locale/plugin.cmd_web.uk.ini +5 -5
  95. pygpt_net/data/locale/plugin.cmd_web.zh.ini +5 -5
  96. pygpt_net/data/locale/plugin.idx_llama_index.de.ini +12 -12
  97. pygpt_net/data/locale/plugin.idx_llama_index.en.ini +12 -12
  98. pygpt_net/data/locale/plugin.idx_llama_index.es.ini +12 -12
  99. pygpt_net/data/locale/plugin.idx_llama_index.fr.ini +12 -12
  100. pygpt_net/data/locale/plugin.idx_llama_index.it.ini +12 -12
  101. pygpt_net/data/locale/plugin.idx_llama_index.pl.ini +12 -12
  102. pygpt_net/data/locale/plugin.idx_llama_index.uk.ini +12 -12
  103. pygpt_net/data/locale/plugin.idx_llama_index.zh.ini +12 -12
  104. pygpt_net/item/attachment.py +9 -1
  105. pygpt_net/item/ctx.py +9 -1
  106. pygpt_net/item/preset.py +5 -1
  107. pygpt_net/launcher.py +3 -1
  108. pygpt_net/migrations/Version20241126170000.py +28 -0
  109. pygpt_net/migrations/__init__.py +3 -1
  110. pygpt_net/plugin/audio_input/__init__.py +11 -1
  111. pygpt_net/plugin/audio_input/worker.py +9 -1
  112. pygpt_net/plugin/audio_output/__init__.py +37 -7
  113. pygpt_net/plugin/audio_output/worker.py +38 -41
  114. pygpt_net/plugin/cmd_code_interpreter/__init__.py +51 -35
  115. pygpt_net/plugin/cmd_code_interpreter/builder.py +16 -4
  116. pygpt_net/plugin/cmd_code_interpreter/config.py +98 -39
  117. pygpt_net/plugin/cmd_code_interpreter/docker.py +4 -0
  118. pygpt_net/plugin/cmd_code_interpreter/ipython/__init__.py +13 -0
  119. pygpt_net/plugin/cmd_code_interpreter/{ipython.py → ipython/docker_kernel.py} +10 -3
  120. pygpt_net/plugin/cmd_code_interpreter/ipython/local_kernel.py +220 -0
  121. pygpt_net/plugin/cmd_code_interpreter/runner.py +5 -5
  122. pygpt_net/plugin/cmd_mouse_control/__init__.py +4 -2
  123. pygpt_net/plugin/cmd_system/config.py +50 -0
  124. pygpt_net/plugin/cmd_system/docker.py +4 -0
  125. pygpt_net/plugin/idx_llama_index/__init__.py +23 -1
  126. pygpt_net/plugin/idx_llama_index/worker.py +10 -0
  127. pygpt_net/plugin/openai_dalle/__init__.py +3 -1
  128. pygpt_net/plugin/openai_vision/__init__.py +3 -1
  129. pygpt_net/provider/core/attachment/json_file.py +4 -1
  130. pygpt_net/provider/core/config/patch.py +25 -0
  131. pygpt_net/provider/core/ctx/db_sqlite/storage.py +14 -4
  132. pygpt_net/provider/core/ctx/db_sqlite/utils.py +19 -2
  133. pygpt_net/provider/core/model/patch.py +7 -1
  134. pygpt_net/provider/core/preset/json_file.py +5 -1
  135. pygpt_net/provider/gpt/__init__.py +14 -2
  136. pygpt_net/provider/gpt/audio.py +63 -0
  137. pygpt_net/provider/gpt/chat.py +76 -44
  138. pygpt_net/provider/gpt/utils.py +27 -0
  139. pygpt_net/provider/gpt/vision.py +37 -15
  140. pygpt_net/provider/loaders/base.py +10 -1
  141. pygpt_net/provider/loaders/web_yt.py +19 -1
  142. pygpt_net/tools/code_interpreter/__init__.py +1 -0
  143. pygpt_net/tools/image_viewer/ui/dialogs.py +3 -1
  144. pygpt_net/ui/dialog/preset.py +3 -1
  145. pygpt_net/ui/dialog/url.py +29 -0
  146. pygpt_net/ui/dialogs.py +5 -1
  147. pygpt_net/ui/layout/chat/attachments.py +42 -6
  148. pygpt_net/ui/layout/chat/attachments_ctx.py +14 -4
  149. pygpt_net/ui/layout/chat/attachments_uploaded.py +8 -4
  150. pygpt_net/ui/layout/toolbox/agent.py +8 -7
  151. pygpt_net/ui/layout/toolbox/agent_llama.py +5 -4
  152. pygpt_net/ui/layout/toolbox/prompt.py +8 -6
  153. pygpt_net/ui/menu/tools.py +17 -11
  154. pygpt_net/ui/widget/anims/toggles.py +167 -0
  155. pygpt_net/ui/widget/dialog/url.py +59 -0
  156. pygpt_net/ui/widget/element/group.py +2 -1
  157. pygpt_net/ui/widget/lists/attachment.py +22 -17
  158. pygpt_net/ui/widget/lists/attachment_ctx.py +65 -3
  159. pygpt_net/ui/widget/option/checkbox.py +69 -5
  160. pygpt_net/ui/widget/option/cmd.py +4 -5
  161. pygpt_net/ui/widget/option/toggle.py +62 -0
  162. pygpt_net/ui/widget/option/toggle_label.py +79 -0
  163. pygpt_net/ui/widget/textarea/url.py +43 -0
  164. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/METADATA +65 -7
  165. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/RECORD +168 -154
  166. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/LICENSE +0 -0
  167. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/WHEEL +0 -0
  168. {pygpt_net-2.4.28.dist-info → pygpt_net-2.4.34.dist-info}/entry_points.txt +0 -0
@@ -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.11.23 00:00:00 #
9
+ # Updated Date: 2024.11.26 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt
13
13
  from PySide6.QtGui import QAction, QIcon, QResizeEvent, QImage
14
14
  from PySide6.QtWidgets import QMenu, QApplication, QHeaderView
15
15
 
16
+ from pygpt_net.item.attachment import AttachmentItem
16
17
  from pygpt_net.ui.widget.lists.base import BaseList
17
18
  from pygpt_net.utils import trans
18
19
  import pygpt_net.icons_rc
@@ -91,9 +92,12 @@ class AttachmentList(BaseList):
91
92
  idx = item.row()
92
93
  preview_actions = []
93
94
  path = None
95
+ attachment = None
94
96
 
95
97
  if idx >= 0:
96
- path = self.window.controller.attachment.get_path_by_idx(mode, idx)
98
+ attachment = self.window.controller.attachment.get_by_idx(mode, idx)
99
+ if attachment:
100
+ path = attachment.path
97
101
  preview_actions = []
98
102
  if self.window.core.filesystem.actions.has_preview(path):
99
103
  preview_actions = self.window.core.filesystem.actions.get_preview(self, path)
@@ -116,21 +120,22 @@ class AttachmentList(BaseList):
116
120
  lambda: self.action_delete(event))
117
121
 
118
122
  menu = QMenu(self)
119
- if idx >= 0 and preview_actions:
120
- for action in preview_actions:
121
- menu.addAction(action)
122
- menu.addAction(actions['open'])
123
- menu.addAction(actions['open_dir'])
124
-
125
- if idx >= 0:
126
- if self.window.core.filesystem.actions.has_use(path):
127
- use_actions = self.window.core.filesystem.actions.get_use(self, path)
128
- use_menu = QMenu(trans('action.use'), self)
129
- for action in use_actions:
130
- use_menu.addAction(action)
131
- menu.addMenu(use_menu)
132
-
133
- menu.addAction(actions['rename'])
123
+ if attachment and attachment.type == AttachmentItem.TYPE_FILE:
124
+ if idx >= 0 and preview_actions:
125
+ for action in preview_actions:
126
+ menu.addAction(action)
127
+
128
+ menu.addAction(actions['open'])
129
+ menu.addAction(actions['open_dir'])
130
+ if idx >= 0:
131
+ if self.window.core.filesystem.actions.has_use(path):
132
+ use_actions = self.window.core.filesystem.actions.get_use(self, path)
133
+ use_menu = QMenu(trans('action.use'), self)
134
+ for action in use_actions:
135
+ use_menu.addAction(action)
136
+ menu.addMenu(use_menu)
137
+
138
+ menu.addAction(actions['rename'])
134
139
  menu.addAction(actions['delete'])
135
140
 
136
141
  if idx >= 0:
@@ -85,18 +85,47 @@ class AttachmentCtxList(BaseList):
85
85
  """
86
86
  actions = {}
87
87
 
88
+ item = self.indexAt(event.pos())
89
+ idx = item.row()
90
+
91
+ has_file = False
92
+ has_src = False
93
+ has_dest = False
94
+
95
+ if idx >= 0:
96
+ has_file = self.window.controller.chat.attachment.has_file_by_idx(idx)
97
+ has_src = self.window.controller.chat.attachment.has_src_by_idx(idx)
98
+ has_dest = self.window.controller.chat.attachment.has_dest_by_idx(idx)
99
+
100
+ actions['open'] = QAction(QIcon(":/icons/view.svg"), trans('action.open'), self)
101
+ actions['open'].triggered.connect(
102
+ lambda: self.action_open(event)
103
+ )
104
+ actions['open_dir_src'] = QAction(QIcon(":/icons/folder.svg"), trans('action.open_dir_src'), self)
105
+ actions['open_dir_src'].triggered.connect(
106
+ lambda: self.action_open_dir_src(event)
107
+ )
108
+ actions['open_dir_dest'] = QAction(QIcon(":/icons/folder.svg"), trans('action.open_dir_storage'), self)
109
+ actions['open_dir_dest'].triggered.connect(
110
+ lambda: self.action_open_dir_dest(event)
111
+ )
112
+
88
113
  actions['delete'] = QAction(QIcon(":/icons/delete.svg"), trans('action.delete'), self)
89
114
  actions['delete'].triggered.connect(
90
115
  lambda: self.action_delete(event)
91
116
  )
92
117
 
93
118
  menu = QMenu(self)
119
+ if has_file:
120
+ menu.addAction(actions['open'])
121
+ if has_src:
122
+ menu.addAction(actions['open_dir_src'])
123
+ if has_dest:
124
+ menu.addAction(actions['open_dir_dest'])
94
125
  menu.addAction(actions['delete'])
95
126
 
96
- item = self.indexAt(event.pos())
97
- idx = item.row()
98
127
  if idx >= 0:
99
- self.window.controller.assistant.files.select(item.row())
128
+ self.window.controller.chat.attachment.select(item.row())
100
129
  menu.exec_(event.globalPos())
101
130
 
102
131
  def action_delete(self, event):
@@ -109,3 +138,36 @@ class AttachmentCtxList(BaseList):
109
138
  idx = item.row()
110
139
  if idx >= 0:
111
140
  self.window.controller.chat.attachment.delete_by_idx(idx)
141
+
142
+ def action_open(self, event):
143
+ """
144
+ Open action handler
145
+
146
+ :param event: mouse event
147
+ """
148
+ item = self.indexAt(event.pos())
149
+ idx = item.row()
150
+ if idx >= 0:
151
+ self.window.controller.chat.attachment.open_by_idx(idx)
152
+
153
+ def action_open_dir_src(self, event):
154
+ """
155
+ Open source directory action handler
156
+
157
+ :param event: mouse event
158
+ """
159
+ item = self.indexAt(event.pos())
160
+ idx = item.row()
161
+ if idx >= 0:
162
+ self.window.controller.chat.attachment.open_dir_src_by_idx(idx)
163
+
164
+ def action_open_dir_dest(self, event):
165
+ """
166
+ Open destination directory action handler
167
+
168
+ :param event: mouse event
169
+ """
170
+ item = self.indexAt(event.pos())
171
+ idx = item.row()
172
+ if idx >= 0:
173
+ self.window.controller.chat.attachment.open_dir_dest_by_idx(idx)
@@ -6,16 +6,25 @@
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.01.19 18:00:00 #
9
+ # Updated Date: 2024.11.24 22:00:00 #
10
10
  # ================================================== #
11
+ from PySide6.QtGui import QIcon
12
+ from PySide6.QtWidgets import QCheckBox, QHBoxLayout, QWidget, QLabel
11
13
 
12
- from PySide6.QtWidgets import QCheckBox, QHBoxLayout, QWidget
13
-
14
+ from pygpt_net.ui.widget.anims.toggles import AnimToggle
14
15
  from pygpt_net.utils import trans
15
16
 
17
+ import pygpt_net.icons_rc
16
18
 
17
19
  class OptionCheckbox(QWidget):
18
- def __init__(self, window=None, parent_id: str = None, id: str = None, option: dict = None):
20
+ def __init__(
21
+ self,
22
+ window=None,
23
+ parent_id: str = None,
24
+ id: str = None,
25
+ option: dict = None,
26
+ icon = None
27
+ ):
19
28
  """
20
29
  Settings checkbox
21
30
 
@@ -23,7 +32,10 @@ class OptionCheckbox(QWidget):
23
32
  :param id: option id
24
33
  :param parent_id: parent option id
25
34
  :param option: option data
35
+ :param icon: icon
26
36
  """
37
+ # TODO: https://pypi.org/project/QtAwesome/
38
+
27
39
  super(OptionCheckbox, self).__init__(window)
28
40
  self.window = window
29
41
  self.id = id
@@ -43,7 +55,8 @@ class OptionCheckbox(QWidget):
43
55
  if "real_time" in self.option:
44
56
  self.real_time = self.option["real_time"]
45
57
 
46
- self.box = QCheckBox(self.title, self.window)
58
+ # self.box = QCheckBox(self.title, self.window)
59
+ self.box = AnimToggle()
47
60
  if self.value is not None:
48
61
  self.box.setChecked(self.value)
49
62
  self.box.stateChanged.connect(
@@ -55,7 +68,58 @@ class OptionCheckbox(QWidget):
55
68
  )
56
69
  )
57
70
 
71
+ self.label = QLabel(self.title)
72
+ self.box = AnimToggle()
73
+
58
74
  self.layout = QHBoxLayout()
59
75
  self.layout.addWidget(self.box)
60
76
 
77
+ # add icon if defined
78
+ if icon is not None:
79
+ ico = QLabel()
80
+ pixmap = QIcon(icon).pixmap(24, 24)
81
+ ico.setPixmap(pixmap)
82
+ self.layout.addWidget(ico)
83
+
84
+
85
+ self.layout.addWidget(self.label)
86
+ self.layout.addStretch()
87
+ self.layout.setContentsMargins(0, 0, 0, 0)
61
88
  self.setLayout(self.layout)
89
+
90
+ # self.layout = QHBoxLayout()
91
+ #self.layout.addWidget(self.box)
92
+
93
+ #self.setLayout(self.layout)
94
+
95
+ def setIcon(self, icon: str):
96
+ """
97
+ Set icon
98
+
99
+ :param icon: icon
100
+ """
101
+ self.box.setIcon(icon)
102
+
103
+ def setText(self, text: str):
104
+ """
105
+ Set label text
106
+
107
+ :param text: text
108
+ """
109
+ self.label.setText(text)
110
+
111
+ def setChecked(self, state: bool):
112
+ """
113
+ Set checkbox state
114
+
115
+ :param state: state
116
+ """
117
+ self.box.setChecked(state)
118
+
119
+ def isChecked(self) -> bool:
120
+ """
121
+ Get checkbox state
122
+
123
+ :return: state
124
+ """
125
+ return self.box.isChecked()
@@ -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.24 06:00:00 #
9
+ # Updated Date: 2024.11.24 22:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtGui import QIcon
@@ -109,8 +109,7 @@ class OptionCmd(QWidget):
109
109
  params_label = QLabel(trans(params_key))
110
110
 
111
111
  # widgets
112
- self.enabled = OptionCheckbox(self.window, parent_id, key_enabled, option_enabled) # enable checkbox
113
- self.enabled.box.setIcon(QIcon(":/icons/terminal.svg"))
112
+ self.enabled = OptionCheckbox(self.window, parent_id, key_enabled, option_enabled, icon = ":/icons/build.svg") # enable checkbox
114
113
  self.params = OptionDict(self.window, parent_id, key_params, option_params) # command params
115
114
  self.instruction = OptionTextarea(self.window, parent_id, key_instruction, option_instruction) # command instruction
116
115
 
@@ -140,8 +139,8 @@ class OptionCmd(QWidget):
140
139
  self.setLayout(self.layout)
141
140
 
142
141
  # show tooltip only if different from description
143
- if txt_tooltip != txt_desc:
144
- self.setToolTip(txt_tooltip)
142
+ # if txt_tooltip != txt_desc:
143
+ # self.setToolTip(txt_tooltip)
145
144
 
146
145
  # update
147
146
  self.update()
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2024.11.24 22:00:00 #
10
+ # ================================================== #
11
+
12
+ from PySide6.QtWidgets import QCheckBox, QHBoxLayout, QWidget
13
+
14
+ from pygpt_net.ui.widget.anims.toggles import AnimToggle
15
+ from pygpt_net.utils import trans
16
+
17
+
18
+ class OptionCheckbox(QWidget):
19
+ def __init__(self, window=None, parent_id: str = None, id: str = None, option: dict = None):
20
+ """
21
+ Settings checkbox
22
+
23
+ :param window: main window
24
+ :param id: option id
25
+ :param parent_id: parent option id
26
+ :param option: option data
27
+ """
28
+ super(OptionCheckbox, self).__init__(window)
29
+ self.window = window
30
+ self.id = id
31
+ self.parent_id = parent_id
32
+ self.option = option
33
+ self.value = False
34
+ self.title = ""
35
+ self.real_time = False
36
+
37
+ # init from option data
38
+ if self.option is not None:
39
+ if "label" in self.option and self.option["label"] is not None \
40
+ and self.option["label"] != "":
41
+ self.title = trans(self.option["label"])
42
+ if "value" in self.option:
43
+ self.value = self.option["value"]
44
+ if "real_time" in self.option:
45
+ self.real_time = self.option["real_time"]
46
+
47
+ self.box = AnimToggle(self.title, self.window)
48
+ if self.value is not None:
49
+ self.box.setChecked(self.value)
50
+ self.box.stateChanged.connect(
51
+ lambda: self.window.controller.config.checkbox.on_update(
52
+ self.parent_id,
53
+ self.id,
54
+ self.option,
55
+ self.box.isChecked()
56
+ )
57
+ )
58
+
59
+ self.layout = QHBoxLayout()
60
+ self.layout.addWidget(self.box)
61
+
62
+ self.setLayout(self.layout)
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2024.11.24 22:00:00 #
10
+ # ================================================== #
11
+ from PySide6.QtGui import QIcon
12
+ from PySide6.QtWidgets import QCheckBox, QHBoxLayout, QWidget, QLabel
13
+
14
+ from pygpt_net.ui.widget.anims.toggles import AnimToggle
15
+ from pygpt_net.utils import trans
16
+
17
+
18
+ class ToggleLabel(QWidget):
19
+ def __init__(
20
+ self,
21
+ title: str = None,
22
+ label_position: str = 'right',
23
+ icon=None,
24
+ icon_size=24,
25
+ parent=None,
26
+ ):
27
+ """
28
+ Toggle checkbox with label
29
+
30
+ :param title: label title
31
+ """
32
+ super(ToggleLabel, self).__init__()
33
+ self.title = title
34
+ self.label = QLabel(self.title)
35
+ self.box = AnimToggle()
36
+
37
+ ico = None
38
+ if icon is not None:
39
+ ico = QLabel()
40
+ pixmap = QIcon(icon).pixmap(icon_size, icon_size)
41
+ ico.setPixmap(pixmap)
42
+
43
+ self.layout = QHBoxLayout()
44
+ if label_position == 'left':
45
+ if icon is not None:
46
+ self.layout.addWidget(ico)
47
+ self.layout.addWidget(self.label)
48
+ self.layout.addWidget(self.box)
49
+ else:
50
+ self.layout.addWidget(self.box)
51
+ if icon is not None:
52
+ self.layout.addWidget(ico)
53
+ self.layout.addWidget(self.label)
54
+ self.layout.setContentsMargins(0, 0, 0, 0)
55
+ self.setLayout(self.layout)
56
+
57
+ def setText(self, text: str):
58
+ """
59
+ Set label text
60
+
61
+ :param text: text
62
+ """
63
+ self.label.setText(text)
64
+
65
+ def setChecked(self, state: bool):
66
+ """
67
+ Set checkbox state
68
+
69
+ :param state: state
70
+ """
71
+ self.box.setChecked(state)
72
+
73
+ def isChecked(self) -> bool:
74
+ """
75
+ Get checkbox state
76
+
77
+ :return: state
78
+ """
79
+ return self.box.isChecked()
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2024.11.26 02:00:00 #
10
+ # ================================================== #
11
+
12
+ from PySide6 import QtCore
13
+ from PySide6.QtWidgets import QLineEdit
14
+
15
+
16
+ class UrlInput(QLineEdit):
17
+ def __init__(self, window=None, id=None):
18
+ """
19
+ Url dialog input
20
+
21
+ :param window: main window
22
+ :param id: info window id
23
+ """
24
+ super(UrlInput, self).__init__(window)
25
+
26
+ self.window = window
27
+ self.id = id
28
+
29
+ def keyPressEvent(self, event):
30
+ """
31
+ Key press event
32
+
33
+ :param event: key event
34
+ """
35
+ super(UrlInput, self).keyPressEvent(event)
36
+
37
+ # save on Enter
38
+ if event.key() == QtCore.Qt.Key_Return or event.key() == QtCore.Qt.Key_Enter:
39
+ self.window.controller.dialogs.confirm.accept_url(
40
+ self.window.ui.dialog['url'].id,
41
+ self.window.ui.dialog['url'].current,
42
+ self.text(),
43
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pygpt-net
3
- Version: 2.4.28
3
+ Version: 2.4.34
4
4
  Summary: Desktop AI Assistant powered by models: OpenAI o1, GPT-4o, GPT-4, GPT-4 Vision, GPT-3.5, DALL-E 3, Llama 3, Mistral, Gemini, Claude, Bielik, and other models supported by Langchain, Llama Index, and Ollama. Features include chatbot, text completion, image generation, vision analysis, speech-to-text, internet access, file handling, command execution and more.
5
5
  Home-page: https://pygpt.net
6
6
  License: MIT
@@ -31,6 +31,7 @@ Requires-Dist: docker (>=7.0.0,<8.0.0)
31
31
  Requires-Dist: docx2txt (>=0.8,<0.9)
32
32
  Requires-Dist: httpx (>=0.27.2,<0.28.0)
33
33
  Requires-Dist: httpx-socks (>=0.9.2,<0.10.0)
34
+ Requires-Dist: ipykernel (>=6.29.5,<7.0.0)
34
35
  Requires-Dist: jupyter_client (>=8.6.3,<9.0.0)
35
36
  Requires-Dist: langchain (>=0.2.14,<0.3.0)
36
37
  Requires-Dist: langchain-community (>=0.2.12,<0.3.0)
@@ -65,7 +66,7 @@ Requires-Dist: llama-index-vector-stores-pinecone (>=0.1.3,<0.2.0)
65
66
  Requires-Dist: llama-index-vector-stores-redis (>=0.1.2,<0.2.0)
66
67
  Requires-Dist: mss (>=9.0.2,<10.0.0)
67
68
  Requires-Dist: nbconvert (>=7.16.1,<8.0.0)
68
- Requires-Dist: openai (>=1.41.0,<1.60.0)
69
+ Requires-Dist: openai (>=1.55.1,<1.60.0)
69
70
  Requires-Dist: opencv-python (>=4.9.0.80,<5.0.0.0)
70
71
  Requires-Dist: packaging (>=23.2,<24.0)
71
72
  Requires-Dist: pandas (>=2.2.0,<3.0.0)
@@ -91,7 +92,7 @@ Description-Content-Type: text/markdown
91
92
 
92
93
  [![pygpt](https://snapcraft.io/pygpt/badge.svg)](https://snapcraft.io/pygpt)
93
94
 
94
- Release: **2.4.28** | build: **2024.11.24** | Python: **>=3.10, <3.12**
95
+ Release: **2.4.34** | build: **2024.11.26** | Python: **>=3.10, <3.12**
95
96
 
96
97
  > Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
97
98
  >
@@ -244,11 +245,11 @@ pip install pygpt-net
244
245
  pygpt
245
246
  ```
246
247
 
247
- ## Source Code
248
+ ## Running from GitHub source code
248
249
 
249
250
  An alternative method is to download the source code from `GitHub` and execute the application using the Python interpreter (>=3.10, <3.12).
250
251
 
251
- ### Running from GitHub source code
252
+ ### Install with pip
252
253
 
253
254
  1. Clone git repository or download .zip file:
254
255
 
@@ -276,7 +277,7 @@ pip install -r requirements.txt
276
277
  python3 run.py
277
278
  ```
278
279
 
279
- **Install with Poetry**
280
+ ### Install with Poetry
280
281
 
281
282
  1. Clone git repository or download .zip file:
282
283
 
@@ -445,7 +446,7 @@ This mode in **PyGPT** mirrors `ChatGPT`, allowing you to chat with models such
445
446
 
446
447
  The main part of the interface is a chat window where conversations appear. Right below that is where you type your messages. On the right side of the screen, there's a section to set up or change your system prompts. You can also save these setups as presets to quickly switch between different models or tasks.
447
448
 
448
- Above where you type your messages, the interface shows you the number of tokens your message will use up as you type it – this helps to keep track of usage. There's also a feature to upload files in this area. Go to the `Files` tab to manage your uploads or add attachments to send to the OpenAI API (but this makes effect only in `Assisant` and `Vision` modes).
449
+ Above where you type your messages, the interface shows you the number of tokens your message will use up as you type it – this helps to keep track of usage. There's also a feature to upload files in this area. Go to the `Attachments` tab to manage your uploads or add attachments to send to the OpenAI API (but this makes effect only in `Assisant` and `Vision` modes).
449
450
 
450
451
  ![v2_mode_chat](https://github.com/szczyglis-dev/py-gpt/assets/61396542/f573ee22-8539-4259-b180-f97e54bc0d94)
451
452
 
@@ -463,6 +464,17 @@ Plugin allows you to generate images in Chat mode:
463
464
 
464
465
  ![v3_img_chat](https://github.com/szczyglis-dev/py-gpt/assets/61396542/c288a4b3-c932-4201-b5a3-8452aea49817)
465
466
 
467
+
468
+ ## Chat with Audio
469
+
470
+ 2024-11-26: currently in beta.
471
+
472
+ This mode works like the Chat mode but with native support for audio input and output using a multimodal model - `gpt-4o-audio`. In this mode, audio input and output are directed to and from the model directly, without the use of external plugins. This enables faster and better audio communication.
473
+
474
+ More info: https://platform.openai.com/docs/guides/audio/quickstart
475
+
476
+ **INFO:** The execution of commands and tools in this mode is temporarily unavailable.
477
+
466
478
  ## Completion
467
479
 
468
480
  This mode provides in-depth access to a broader range of capabilities offered by Large Language Models (LLMs). While it maintains a chat-like interface for user interaction, it introduces additional settings and functional richness beyond typical chat exchanges. Users can leverage this mode to prompt models for complex text completions, role-play dialogues between different characters, perform text analysis, and execute a variety of other sophisticated tasks. It supports any model provided by the OpenAI API as well as other models through `Langchain`.
@@ -1186,6 +1198,10 @@ The content from the uploaded attachments will be used in the current conversati
1186
1198
 
1187
1199
  **Note:** Only text files from the list above are included in the additional context. Images will not be included in the context but will be used by the vision model in real-time. Adding image files to the context will be available in future versions.
1188
1200
 
1201
+ **Uploading larger files and auto-index:**
1202
+
1203
+ To use the `Query only` mode, the file must be indexed in the vector database. This occurs automatically at the time of upload if the `Auto-index on upload` option in the `Attachments` tab is enabled. When uploading large files, such indexing might take a while - therefore, if you are using the `Full context` option, which does not use the index, you can disable the `Auto-index` option to speed up the upload of the attachment. In this case, it will only be indexed when the `Query only` option is called for the first time, and until then, attachment will be available in the form of `Full context` and `Summary`.
1204
+
1189
1205
  ## Files (download, code generation)
1190
1206
 
1191
1207
  **PyGPT** enables the automatic download and saving of files created by the model. This is carried out in the background, with the files being saved to an `data` folder located within the user's working directory. To view or manage these files, users can navigate to the `Files` tab which features a file browser for this specific directory. Here, users have the interface to handle all files sent by the AI.
@@ -1654,6 +1670,8 @@ Python code to a file, which the `Code Interpreter` can execute it and return it
1654
1670
  - `Files I/O` - provides access to the local filesystem, enabling GPT to read and write files,
1655
1671
  as well as list and create directories.
1656
1672
 
1673
+ - `System (OS)` - allows you to create and execute custom commands on your system.
1674
+
1657
1675
  - `Mouse and Keyboard` - provides the ability to control the mouse and keyboard by the model.
1658
1676
 
1659
1677
  - `Web Search` - provides the ability to connect to the Web, search web pages for current data, and index external content using Llama-index data loaders.
@@ -3741,6 +3759,46 @@ may consume additional tokens that are not displayed in the main window.
3741
3759
 
3742
3760
  ## Recent changes:
3743
3761
 
3762
+ **2.4.34 (2024-11-26)**
3763
+
3764
+ - Added a new mode: `Chat with Audio`, with built-in multimodal support for audio input/output. Currently in `beta`, the execution of commands and tools in this mode is temporarily unavailable.
3765
+ - Added new models: `gpt-4o-audio-preview`, `gpt-4o-2024-11-20`, `chatgpt-4o-latest`.
3766
+ - Force disabled integration with the native system menu.
3767
+
3768
+ **2.4.33 (2024-11-26)**
3769
+
3770
+ - Improved CSS and rendering of file and image lists.
3771
+ - Added displaying of used attachments in the chat window.
3772
+
3773
+ **2.4.32 (2024-11-26)**
3774
+
3775
+ - The "Add URL" option added to the "Attachments" tab allows users to include content from a given website as additional context. Currently, it only supports standard web pages and video transcription for YouTube links. More "web" options will be added in the future.
3776
+ - Added UTF-8 as default in attachments content text read/write.
3777
+
3778
+ **2.4.31 (2024-11-25)**
3779
+
3780
+ - Added an option checkbox `Auto-index on upload` in the `Attachments` tab:
3781
+
3782
+ **Tip:** To use the `Query only` mode, the file must be indexed in the vector database. This occurs automatically at the time of upload if the `Auto-index on upload` option in the `Attachments` tab is enabled. When uploading large files, such indexing might take a while - therefore, if you are using the `Full context` option, which does not use the index, you can disable the `Auto-index` option to speed up the upload of the attachment. In this case, it will only be indexed when the `Query only` option is called for the first time, and until then, attachment will be available in the form of `Full context` and `Summary`.
3783
+
3784
+ - Added context menu options in `Uploaded attachments` tab: `Open`, `Open Source directory` and `Open Storage directory`.
3785
+
3786
+ **2.4.30 (2024-11-25)**
3787
+
3788
+ - Added instruction to model about mapped data directory in both legacy and IPython code interepreter.
3789
+ - Updated locales for plugins.
3790
+
3791
+ **2.4.29 (2024-11-25)**
3792
+
3793
+ - Added a local IPython interpreter - you can now choose between local and sandbox (Docker) in the plugin settings.
3794
+ - Added the ability to configure mapped volumes and ports for Docker containers in the plugin settings.
3795
+ - Optimized and speed-up the Llama-index plugin (inline).
3796
+ - Checkboxes replaced with Toggle buttons.
3797
+ - Improved settings dialogs.
3798
+ - Slight modification of the layout.
3799
+ - Fix: Dockerfile formatting in Code Interpreter config.
3800
+ - Fix: experts inline plugin execution.
3801
+
3744
3802
  **2.4.28 (2024-11-24)**
3745
3803
 
3746
3804
  - Fix: issue #78