pygpt-net 2.4.31__py3-none-any.whl → 2.4.33__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 (51) hide show
  1. CHANGELOG.md +10 -0
  2. README.md +14 -4
  3. pygpt_net/CHANGELOG.txt +10 -0
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/controller/attachment.py +52 -1
  6. pygpt_net/controller/chat/attachment.py +109 -44
  7. pygpt_net/controller/dialogs/confirm.py +17 -1
  8. pygpt_net/core/attachments/__init__.py +11 -7
  9. pygpt_net/core/attachments/context.py +171 -34
  10. pygpt_net/core/debug/attachments.py +3 -1
  11. pygpt_net/core/debug/context.py +5 -1
  12. pygpt_net/core/idx/indexing.py +123 -15
  13. pygpt_net/core/render/markdown/pid.py +2 -1
  14. pygpt_net/core/render/plain/pid.py +2 -1
  15. pygpt_net/core/render/web/body.py +34 -12
  16. pygpt_net/core/render/web/pid.py +2 -1
  17. pygpt_net/core/render/web/renderer.py +8 -3
  18. pygpt_net/data/config/config.json +3 -3
  19. pygpt_net/data/config/models.json +3 -3
  20. pygpt_net/data/config/modes.json +3 -3
  21. pygpt_net/data/css/web.css +70 -0
  22. pygpt_net/data/css/web.dark.css +4 -1
  23. pygpt_net/data/css/web.light.css +1 -1
  24. pygpt_net/data/locale/locale.de.ini +7 -1
  25. pygpt_net/data/locale/locale.en.ini +10 -4
  26. pygpt_net/data/locale/locale.es.ini +7 -1
  27. pygpt_net/data/locale/locale.fr.ini +7 -1
  28. pygpt_net/data/locale/locale.it.ini +7 -1
  29. pygpt_net/data/locale/locale.pl.ini +7 -1
  30. pygpt_net/data/locale/locale.uk.ini +7 -1
  31. pygpt_net/data/locale/locale.zh.ini +7 -1
  32. pygpt_net/item/attachment.py +9 -1
  33. pygpt_net/plugin/cmd_code_interpreter/runner.py +2 -2
  34. pygpt_net/plugin/cmd_mouse_control/__init__.py +4 -2
  35. pygpt_net/provider/core/attachment/json_file.py +4 -1
  36. pygpt_net/provider/loaders/base.py +10 -1
  37. pygpt_net/provider/loaders/web_yt.py +19 -1
  38. pygpt_net/tools/image_viewer/ui/dialogs.py +3 -1
  39. pygpt_net/ui/dialog/url.py +29 -0
  40. pygpt_net/ui/dialogs.py +5 -1
  41. pygpt_net/ui/layout/chat/attachments.py +20 -6
  42. pygpt_net/ui/layout/chat/attachments_ctx.py +4 -3
  43. pygpt_net/ui/layout/chat/attachments_uploaded.py +8 -4
  44. pygpt_net/ui/widget/dialog/url.py +59 -0
  45. pygpt_net/ui/widget/lists/attachment.py +22 -17
  46. pygpt_net/ui/widget/textarea/url.py +43 -0
  47. {pygpt_net-2.4.31.dist-info → pygpt_net-2.4.33.dist-info}/METADATA +15 -5
  48. {pygpt_net-2.4.31.dist-info → pygpt_net-2.4.33.dist-info}/RECORD +51 -48
  49. {pygpt_net-2.4.31.dist-info → pygpt_net-2.4.33.dist-info}/LICENSE +0 -0
  50. {pygpt_net-2.4.31.dist-info → pygpt_net-2.4.33.dist-info}/WHEEL +0 -0
  51. {pygpt_net-2.4.31.dist-info → pygpt_net-2.4.33.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: 2024.03.26 15:00:00 #
9
+ # Updated Date: 2024.11.26 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt
@@ -17,6 +17,8 @@ from pygpt_net.ui.widget.dialog.base import BaseDialog
17
17
  from pygpt_net.ui.widget.image.display import ImageLabel
18
18
  from pygpt_net.utils import trans
19
19
 
20
+ import pygpt_net.icons_rc
21
+
20
22
  class DialogSpawner:
21
23
  def __init__(self, window=None):
22
24
  """
@@ -0,0 +1,29 @@
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 pygpt_net.ui.widget.dialog.url import UrlDialog
13
+ from pygpt_net.utils import trans
14
+
15
+
16
+ class Url:
17
+ def __init__(self, window=None):
18
+ """
19
+ URL dialog
20
+
21
+ :param window: Window instance
22
+ """
23
+ self.window = window
24
+
25
+ def setup(self):
26
+ """Setup URL dialog"""
27
+ id = 'url'
28
+ self.window.ui.dialog[id] = UrlDialog(self.window, id)
29
+ self.window.ui.dialog[id].setWindowTitle(trans("dialog.url.title"))
pygpt_net/ui/dialogs.py CHANGED
@@ -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.14 01:00:00 #
9
+ # Updated Date: 2024.11.26 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import threading
@@ -35,6 +35,7 @@ from pygpt_net.ui.dialog.settings import Settings
35
35
  from pygpt_net.ui.dialog.snap import Snap
36
36
  from pygpt_net.ui.dialog.start import Start
37
37
  from pygpt_net.ui.dialog.update import Update
38
+ from pygpt_net.ui.dialog.url import Url
38
39
  from pygpt_net.ui.dialog.workdir import Workdir
39
40
  from pygpt_net.ui.widget.dialog.alert import AlertDialog
40
41
  from pygpt_net.ui.widget.dialog.confirm import ConfirmDialog
@@ -66,6 +67,7 @@ class Dialogs:
66
67
  self.snap = Snap(self.window)
67
68
  self.start = Start(self.window)
68
69
  self.update = Update(self.window)
70
+ self.url = Url(self.window)
69
71
  self.workdir = Workdir(self.window)
70
72
 
71
73
  def setup(self):
@@ -85,6 +87,8 @@ class Dialogs:
85
87
  self.snap.setup()
86
88
  self.start.setup()
87
89
  self.update.setup()
90
+ self.url.setup()
91
+
88
92
  self.image.setup()
89
93
  self.license.setup()
90
94
  self.logger.setup()
@@ -6,18 +6,20 @@
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
  import os
13
13
 
14
- from PySide6.QtGui import QStandardItemModel, Qt
14
+ from PySide6.QtGui import QStandardItemModel, Qt, QIcon
15
15
  from PySide6.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QCheckBox, QWidget
16
16
 
17
+ from pygpt_net.item.attachment import AttachmentItem
17
18
  from pygpt_net.ui.widget.element.labels import HelpLabel
18
19
  from pygpt_net.ui.widget.lists.attachment import AttachmentList
19
20
  from pygpt_net.utils import trans
20
21
 
22
+ import pygpt_net.icons_rc
21
23
 
22
24
  class Attachments:
23
25
  def __init__(self, window=None):
@@ -38,13 +40,21 @@ class Attachments:
38
40
  self.setup_attachments()
39
41
  self.setup_buttons()
40
42
 
43
+ empty_widget = QWidget()
44
+ self.window.ui.nodes['input.attachments.options.label'] = HelpLabel(trans("attachments.options.label"))
45
+
41
46
  # buttons layout
42
47
  buttons = QHBoxLayout()
43
48
  buttons.addWidget(self.window.ui.nodes['attachments.btn.add'])
49
+ buttons.addWidget(self.window.ui.nodes['attachments.btn.add_url'])
44
50
  buttons.addWidget(self.window.ui.nodes['attachments.btn.clear'])
51
+ buttons.addWidget(empty_widget)
52
+ buttons.addWidget(self.window.ui.nodes['input.attachments.options.label'])
53
+
45
54
  buttons.addWidget(self.setup_auto_index())
46
55
  buttons.addWidget(self.setup_send_clear())
47
56
  buttons.addWidget(self.setup_capture_clear())
57
+ buttons.addStretch()
48
58
 
49
59
  self.window.ui.nodes['tip.input.attachments'] = HelpLabel(trans('tip.input.attachments'), self.window)
50
60
 
@@ -109,11 +119,14 @@ class Attachments:
109
119
  """
110
120
  Setup buttons
111
121
  """
112
- self.window.ui.nodes['attachments.btn.add'] = QPushButton(trans('attachments.btn.add'))
113
- self.window.ui.nodes['attachments.btn.clear'] = QPushButton(trans('attachments.btn.clear'))
122
+ self.window.ui.nodes['attachments.btn.add'] = QPushButton(QIcon(":/icons/add.svg"), trans('attachments.btn.add'))
123
+ self.window.ui.nodes['attachments.btn.add_url'] = QPushButton(QIcon(":/icons/add.svg"), trans('attachments.btn.add_url'))
124
+ self.window.ui.nodes['attachments.btn.clear'] = QPushButton(QIcon(":/icons/close.svg"), trans('attachments.btn.clear'))
114
125
 
115
126
  self.window.ui.nodes['attachments.btn.add'].clicked.connect(
116
127
  lambda: self.window.controller.attachment.open_add())
128
+ self.window.ui.nodes['attachments.btn.add_url'].clicked.connect(
129
+ lambda: self.window.controller.attachment.open_add_url())
117
130
  self.window.ui.nodes['attachments.btn.clear'].clicked.connect(
118
131
  lambda: self.window.controller.attachment.clear(remove_local=True))
119
132
 
@@ -166,8 +179,9 @@ class Attachments:
166
179
  for id in data:
167
180
  path = data[id].path
168
181
  size = ""
169
- if path and os.path.exists(path):
170
- size = self.window.core.filesystem.sizeof_fmt(os.path.getsize(path))
182
+ if data[id].type == AttachmentItem.TYPE_FILE:
183
+ if path and os.path.exists(path):
184
+ size = self.window.core.filesystem.sizeof_fmt(os.path.getsize(path))
171
185
  ctx_str = ""
172
186
  if data[id].ctx:
173
187
  ctx_str = "YES"
@@ -6,19 +6,20 @@
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
  import os
13
13
 
14
14
  from PySide6 import QtCore
15
- from PySide6.QtGui import QStandardItemModel, Qt
15
+ from PySide6.QtGui import QStandardItemModel, Qt, QIcon
16
16
  from PySide6.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QWidget, QRadioButton
17
17
 
18
18
  from pygpt_net.ui.widget.element.labels import HelpLabel
19
19
  from pygpt_net.ui.widget.lists.attachment_ctx import AttachmentCtxList
20
20
  from pygpt_net.utils import trans
21
21
 
22
+ import pygpt_net.icons_rc
22
23
 
23
24
  class AttachmentsCtx:
24
25
  def __init__(self, window=None):
@@ -90,7 +91,7 @@ class AttachmentsCtx:
90
91
  self.window.ui.nodes[self.id] = AttachmentCtxList(self.window)
91
92
 
92
93
  # buttons
93
- self.window.ui.nodes['attachments_ctx.btn.clear'] = QPushButton(trans('attachments_uploaded.btn.clear'))
94
+ self.window.ui.nodes['attachments_ctx.btn.clear'] = QPushButton(QIcon(":/icons/close.svg"), trans('attachments_uploaded.btn.clear'))
94
95
  self.window.ui.nodes['attachments_ctx.btn.clear'].clicked.connect(
95
96
  lambda: self.window.controller.chat.attachment.clear()
96
97
  )
@@ -12,7 +12,7 @@
12
12
  import os
13
13
 
14
14
  from PySide6 import QtCore
15
- from PySide6.QtGui import QStandardItemModel, Qt
15
+ from PySide6.QtGui import QStandardItemModel, Qt, QIcon
16
16
  from PySide6.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QCheckBox, QLabel, QWidget
17
17
 
18
18
  from pygpt_net.ui.widget.element.button import SyncButton
@@ -20,6 +20,7 @@ from pygpt_net.ui.widget.element.labels import HelpLabel
20
20
  from pygpt_net.ui.widget.lists.uploaded import UploadedFileList
21
21
  from pygpt_net.utils import trans
22
22
 
23
+ import pygpt_net.icons_rc
23
24
 
24
25
  class AttachmentsUploaded:
25
26
  def __init__(self, window=None):
@@ -38,10 +39,11 @@ class AttachmentsUploaded:
38
39
  :return: QVBoxLayout
39
40
  """
40
41
  self.setup_attachments()
42
+ empty_widget = QWidget()
41
43
 
42
- self.window.ui.nodes['attachments_uploaded.sync.tip'] = QLabel(trans('attachments_uploaded.sync.tip'))
44
+ self.window.ui.nodes['attachments_uploaded.sync.tip'] = HelpLabel(trans('attachments_uploaded.sync.tip'))
45
+ self.window.ui.nodes['attachments_uploaded.sync.tip'].setWordWrap(False)
43
46
  self.window.ui.nodes['attachments_uploaded.sync.tip'].setAlignment(Qt.AlignCenter)
44
- empty_widget = QWidget()
45
47
 
46
48
  self.window.ui.nodes['tip.input.attachments.uploaded'] = HelpLabel(trans('tip.input.attachments.uploaded'),
47
49
  self.window)
@@ -52,6 +54,8 @@ class AttachmentsUploaded:
52
54
  buttons_layout.addWidget(self.window.ui.nodes['attachments_uploaded.btn.clear'])
53
55
  buttons_layout.addWidget(empty_widget)
54
56
  buttons_layout.addWidget(self.window.ui.nodes['attachments_uploaded.sync.tip'])
57
+ buttons_layout.addStretch()
58
+
55
59
 
56
60
  # layout
57
61
  layout = QVBoxLayout()
@@ -70,7 +74,7 @@ class AttachmentsUploaded:
70
74
 
71
75
  # buttons
72
76
  self.window.ui.nodes['attachments_uploaded.btn.sync'] = SyncButton(trans('attachments_uploaded.btn.sync'), self.window)
73
- self.window.ui.nodes['attachments_uploaded.btn.clear'] = QPushButton(trans('attachments_uploaded.btn.clear'))
77
+ self.window.ui.nodes['attachments_uploaded.btn.clear'] = QPushButton(QIcon(":/icons/close.svg"), trans('attachments_uploaded.btn.clear'))
74
78
  self.window.ui.nodes['attachments_uploaded.btn.clear'].clicked.connect(
75
79
  lambda: self.window.controller.assistant.files.clear()
76
80
  )
@@ -0,0 +1,59 @@
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.QtWidgets import QDialog, QLabel, QHBoxLayout, QVBoxLayout, QPushButton
13
+
14
+ from pygpt_net.ui.widget.element.labels import HelpLabel
15
+ from pygpt_net.utils import trans
16
+ from pygpt_net.ui.widget.textarea.url import UrlInput
17
+
18
+
19
+ class UrlDialog(QDialog):
20
+ def __init__(self, window=None, id=None):
21
+ """
22
+ Url dialog
23
+
24
+ :param window: main window
25
+ :param id: info window id
26
+ """
27
+ super(UrlDialog, self).__init__(window)
28
+ self.window = window
29
+ self.id = id
30
+ self.current = None
31
+ self.input = UrlInput(window, id)
32
+ self.input.setMinimumWidth(400)
33
+
34
+ self.window.ui.nodes['dialog.url.btn.update'] = QPushButton(trans('dialog.url.update'))
35
+ self.window.ui.nodes['dialog.url.btn.update'].clicked.connect(
36
+ lambda: self.window.controller.dialogs.confirm.accept_url(
37
+ self.id,
38
+ self.window.ui.dialog['url'].current,
39
+ self.input.text()),
40
+ )
41
+
42
+ self.window.ui.nodes['dialog.url.btn.dismiss'] = QPushButton(trans('dialog.url.dismiss'))
43
+ self.window.ui.nodes['dialog.url.btn.dismiss'].clicked.connect(
44
+ lambda: self.window.controller.dialogs.confirm.dismiss_url())
45
+
46
+ bottom = QHBoxLayout()
47
+ bottom.addWidget(self.window.ui.nodes['dialog.url.btn.dismiss'])
48
+ bottom.addWidget(self.window.ui.nodes['dialog.url.btn.update'])
49
+
50
+ self.window.ui.nodes['dialog.url.label'] = QLabel(trans("dialog.url.title"))
51
+ self.window.ui.nodes['dialog.url.tip'] = HelpLabel(trans("dialog.url.tip"))
52
+
53
+ layout = QVBoxLayout()
54
+ layout.addWidget(self.window.ui.nodes['dialog.url.label'])
55
+ layout.addWidget(self.input)
56
+ layout.addWidget(self.window.ui.nodes['dialog.url.tip'])
57
+ layout.addLayout(bottom)
58
+
59
+ self.setLayout(layout)
@@ -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:
@@ -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.31
3
+ Version: 2.4.33
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
@@ -92,7 +92,7 @@ Description-Content-Type: text/markdown
92
92
 
93
93
  [![pygpt](https://snapcraft.io/pygpt/badge.svg)](https://snapcraft.io/pygpt)
94
94
 
95
- Release: **2.4.31** | build: **2024.11.25** | Python: **>=3.10, <3.12**
95
+ Release: **2.4.33** | build: **2024.11.26** | Python: **>=3.10, <3.12**
96
96
 
97
97
  > Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
98
98
  >
@@ -245,11 +245,11 @@ pip install pygpt-net
245
245
  pygpt
246
246
  ```
247
247
 
248
- ## Source Code
248
+ ## Running from GitHub source code
249
249
 
250
250
  An alternative method is to download the source code from `GitHub` and execute the application using the Python interpreter (>=3.10, <3.12).
251
251
 
252
- ### Running from GitHub source code
252
+ ### Install with pip
253
253
 
254
254
  1. Clone git repository or download .zip file:
255
255
 
@@ -277,7 +277,7 @@ pip install -r requirements.txt
277
277
  python3 run.py
278
278
  ```
279
279
 
280
- **Install with Poetry**
280
+ ### Install with Poetry
281
281
 
282
282
  1. Clone git repository or download .zip file:
283
283
 
@@ -3746,6 +3746,16 @@ may consume additional tokens that are not displayed in the main window.
3746
3746
 
3747
3747
  ## Recent changes:
3748
3748
 
3749
+ **2.4.33 (2024-11-26)**
3750
+
3751
+ - Improved CSS and rendering of file and image lists.
3752
+ - Added displaying of used attachments in the chat window.
3753
+
3754
+ **2.4.32 (2024-11-26)**
3755
+
3756
+ - 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.
3757
+ - Added UTF-8 as default in attachments content text read/write.
3758
+
3749
3759
  **2.4.31 (2024-11-25)**
3750
3760
 
3751
3761
  - Added an option checkbox `Auto-index on upload` in the `Attachments` tab: