pygpt-net 2.4.42__py3-none-any.whl → 2.4.45__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.
- CHANGELOG.md +15 -0
- README.md +21 -2
- pygpt_net/CHANGELOG.txt +15 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/attachment.py +31 -3
- pygpt_net/controller/chat/attachment.py +37 -36
- pygpt_net/controller/config/placeholder.py +6 -4
- pygpt_net/controller/idx/common.py +7 -3
- pygpt_net/controller/lang/mapping.py +32 -9
- pygpt_net/core/attachments/__init__.py +7 -2
- pygpt_net/core/attachments/context.py +52 -34
- pygpt_net/core/db/__init__.py +2 -1
- pygpt_net/core/debug/attachments.py +1 -0
- pygpt_net/core/idx/__init__.py +8 -3
- pygpt_net/core/idx/indexing.py +24 -7
- pygpt_net/core/idx/ui/__init__.py +22 -0
- pygpt_net/core/idx/ui/loaders.py +217 -0
- pygpt_net/data/config/config.json +4 -4
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/modes.json +3 -3
- pygpt_net/data/config/settings.json +5 -5
- pygpt_net/data/css/style.css +1 -0
- pygpt_net/data/locale/locale.de.ini +4 -4
- pygpt_net/data/locale/locale.en.ini +11 -9
- pygpt_net/data/locale/locale.es.ini +4 -4
- pygpt_net/data/locale/locale.fr.ini +4 -4
- pygpt_net/data/locale/locale.it.ini +4 -4
- pygpt_net/data/locale/locale.pl.ini +4 -4
- pygpt_net/data/locale/locale.uk.ini +4 -4
- pygpt_net/data/locale/locale.zh.ini +4 -4
- pygpt_net/data/locale/plugin.mailer.en.ini +5 -5
- pygpt_net/item/attachment.py +5 -1
- pygpt_net/item/ctx.py +99 -2
- pygpt_net/migrations/Version20241215110000.py +25 -0
- pygpt_net/migrations/__init__.py +3 -1
- pygpt_net/plugin/cmd_files/__init__.py +3 -2
- pygpt_net/provider/core/attachment/json_file.py +4 -1
- pygpt_net/provider/core/config/patch.py +12 -0
- pygpt_net/provider/core/ctx/db_sqlite/storage.py +50 -7
- pygpt_net/provider/core/ctx/db_sqlite/utils.py +29 -5
- pygpt_net/provider/loaders/base.py +14 -0
- pygpt_net/provider/loaders/hub/google/gmail.py +2 -2
- pygpt_net/provider/loaders/hub/yt/base.py +5 -0
- pygpt_net/provider/loaders/web_database.py +13 -5
- pygpt_net/provider/loaders/web_github_issues.py +18 -1
- pygpt_net/provider/loaders/web_github_repo.py +10 -0
- pygpt_net/provider/loaders/web_google_calendar.py +9 -1
- pygpt_net/provider/loaders/web_google_docs.py +6 -1
- pygpt_net/provider/loaders/web_google_drive.py +10 -1
- pygpt_net/provider/loaders/web_google_gmail.py +5 -3
- pygpt_net/provider/loaders/web_google_keep.py +5 -1
- pygpt_net/provider/loaders/web_google_sheets.py +5 -1
- pygpt_net/provider/loaders/web_microsoft_onedrive.py +15 -1
- pygpt_net/provider/loaders/web_page.py +4 -2
- pygpt_net/provider/loaders/web_rss.py +3 -1
- pygpt_net/provider/loaders/web_sitemap.py +9 -3
- pygpt_net/provider/loaders/web_twitter.py +4 -2
- pygpt_net/provider/loaders/web_yt.py +17 -2
- pygpt_net/provider/vector_stores/ctx_attachment.py +1 -1
- pygpt_net/tools/indexer/__init__.py +8 -40
- pygpt_net/tools/indexer/ui/web.py +33 -80
- pygpt_net/ui/layout/ctx/ctx_list.py +86 -18
- pygpt_net/ui/widget/dialog/url.py +162 -14
- pygpt_net/ui/widget/element/group.py +15 -2
- pygpt_net/ui/widget/lists/context.py +23 -9
- pygpt_net/utils.py +1 -1
- {pygpt_net-2.4.42.dist-info → pygpt_net-2.4.45.dist-info}/METADATA +22 -3
- {pygpt_net-2.4.42.dist-info → pygpt_net-2.4.45.dist-info}/RECORD +71 -68
- {pygpt_net-2.4.42.dist-info → pygpt_net-2.4.45.dist-info}/LICENSE +0 -0
- {pygpt_net-2.4.42.dist-info → pygpt_net-2.4.45.dist-info}/WHEEL +0 -0
- {pygpt_net-2.4.42.dist-info → pygpt_net-2.4.45.dist-info}/entry_points.txt +0 -0
@@ -6,12 +6,16 @@
|
|
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.
|
9
|
+
# Updated Date: 2024.12.16 01:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
|
-
from PySide6.
|
12
|
+
from PySide6.QtCore import Qt
|
13
|
+
from PySide6.QtGui import QIcon
|
14
|
+
from PySide6.QtWidgets import QDialog, QLabel, QHBoxLayout, QVBoxLayout, QPushButton, QScrollArea, QWidget, QSizePolicy
|
13
15
|
|
14
|
-
from pygpt_net.ui.widget.element.
|
16
|
+
from pygpt_net.ui.widget.element.group import QHLine
|
17
|
+
from pygpt_net.ui.widget.element.labels import HelpLabel, UrlLabel, IconLabel
|
18
|
+
from pygpt_net.ui.widget.option.combo import OptionCombo
|
15
19
|
from pygpt_net.utils import trans
|
16
20
|
from pygpt_net.ui.widget.textarea.url import UrlInput
|
17
21
|
|
@@ -28,15 +32,19 @@ class UrlDialog(QDialog):
|
|
28
32
|
self.window = window
|
29
33
|
self.id = id
|
30
34
|
self.current = None
|
31
|
-
self.input = UrlInput(window, id)
|
32
|
-
self.input.setMinimumWidth(400)
|
35
|
+
#self.input = UrlInput(window, id)
|
36
|
+
#self.input.setMinimumWidth(400)
|
37
|
+
self.initialized = False
|
38
|
+
self.params_scroll = None
|
39
|
+
|
40
|
+
def init(self):
|
41
|
+
"""Initialize dialog"""
|
42
|
+
if self.initialized:
|
43
|
+
return
|
33
44
|
|
34
45
|
self.window.ui.nodes['dialog.url.btn.update'] = QPushButton(trans('dialog.url.update'))
|
35
46
|
self.window.ui.nodes['dialog.url.btn.update'].clicked.connect(
|
36
|
-
lambda: self.window.controller.
|
37
|
-
self.id,
|
38
|
-
self.window.ui.dialog['url'].current,
|
39
|
-
self.input.text()),
|
47
|
+
lambda: self.window.controller.attachment.attach_url()
|
40
48
|
)
|
41
49
|
|
42
50
|
self.window.ui.nodes['dialog.url.btn.dismiss'] = QPushButton(trans('dialog.url.dismiss'))
|
@@ -47,13 +55,153 @@ class UrlDialog(QDialog):
|
|
47
55
|
bottom.addWidget(self.window.ui.nodes['dialog.url.btn.dismiss'])
|
48
56
|
bottom.addWidget(self.window.ui.nodes['dialog.url.btn.update'])
|
49
57
|
|
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"))
|
58
|
+
#self.window.ui.nodes['dialog.url.label'] = QLabel(trans("dialog.url.title"))
|
59
|
+
#self.window.ui.nodes['dialog.url.tip'] = HelpLabel(trans("dialog.url.tip"))
|
60
|
+
|
61
|
+
# -----------------
|
62
|
+
|
63
|
+
loaders = self.window.controller.config.placeholder.apply_by_id("llama_index_loaders_web")
|
64
|
+
loaders_list = []
|
65
|
+
for loader in loaders:
|
66
|
+
k = list(loader.keys())[0]
|
67
|
+
key = k.replace("web_", "")
|
68
|
+
value = loader[k]
|
69
|
+
loaders_list.append({
|
70
|
+
key: value,
|
71
|
+
})
|
72
|
+
|
73
|
+
self.window.ui.nodes["dialog.url.loader"] = OptionCombo(
|
74
|
+
self.window,
|
75
|
+
"dialog.url",
|
76
|
+
"web.loader",
|
77
|
+
{
|
78
|
+
"label": trans("tool.indexer.tab.web.loader"),
|
79
|
+
"keys": loaders_list,
|
80
|
+
"value": "webpage",
|
81
|
+
}
|
82
|
+
)
|
83
|
+
|
84
|
+
self.window.ui.nodes["dialog.url.loader"].layout.setContentsMargins(0, 0, 0, 0)
|
85
|
+
self.window.ui.nodes["dialog.url.loader.label"] = HelpLabel(trans("tool.indexer.tab.web.loader"))
|
86
|
+
self.window.ui.add_hook("update.dialog.url.web.loader", self.hook_loader_change)
|
87
|
+
|
88
|
+
self.window.ui.nodes["dialog.url.options.label"] = HelpLabel(trans("tool.indexer.tab.web.source"))
|
89
|
+
|
90
|
+
config_label = HelpLabel(trans("tool.indexer.tab.web.cfg"))
|
91
|
+
config_label.setWordWrap(False)
|
92
|
+
|
93
|
+
config_label_layout = QHBoxLayout()
|
94
|
+
config_label_layout.addWidget(IconLabel(QIcon(":/icons/settings_filled.svg")))
|
95
|
+
config_label_layout.addWidget(config_label)
|
96
|
+
config_label_layout.setAlignment(Qt.AlignLeft)
|
97
|
+
|
98
|
+
self.window.ui.nodes["dialog.url.config.label"] = QWidget()
|
99
|
+
self.window.ui.nodes["dialog.url.config.label"].setLayout(config_label_layout)
|
100
|
+
|
101
|
+
self.window.ui.nodes["dialog.url.config.help"] = UrlLabel(
|
102
|
+
trans("tool.indexer.tab.web.help"),
|
103
|
+
"https://pygpt.readthedocs.io/en/latest/configuration.html#data-loaders")
|
104
|
+
|
105
|
+
params_layout = QVBoxLayout()
|
106
|
+
params_layout.setContentsMargins(0, 0, 0, 0)
|
107
|
+
|
108
|
+
self.params_scroll = QScrollArea()
|
109
|
+
self.params_scroll.setWidgetResizable(True)
|
110
|
+
self.window.ui.nodes["dialog.url.loader.option"] = {}
|
111
|
+
self.window.ui.nodes["dialog.url.loader.option_group"] = {}
|
112
|
+
self.window.ui.nodes["dialog.url.loader.config"] = {}
|
113
|
+
self.window.ui.nodes["dialog.url.loader.config_group"] = {}
|
114
|
+
|
115
|
+
# params
|
116
|
+
params_layout.addWidget(self.window.ui.nodes["dialog.url.options.label"])
|
117
|
+
inputs, groups = self.window.core.idx.ui.loaders.setup_loader_options()
|
118
|
+
|
119
|
+
for loader in inputs:
|
120
|
+
for k in inputs[loader]:
|
121
|
+
self.window.ui.nodes["dialog.url.loader.option." + loader + "." + k] = inputs[loader][k]
|
122
|
+
for loader in groups:
|
123
|
+
self.window.ui.nodes["dialog.url.loader.option_group"][loader] = groups[loader]
|
124
|
+
params_layout.addWidget(self.window.ui.nodes["dialog.url.loader.option_group"][loader])
|
125
|
+
self.window.ui.nodes["dialog.url.loader.option_group"][loader].hide() # hide on start
|
126
|
+
|
127
|
+
# separator
|
128
|
+
params_layout.addWidget(QHLine())
|
129
|
+
|
130
|
+
# config
|
131
|
+
params_layout.addWidget(self.window.ui.nodes["dialog.url.config.label"])
|
132
|
+
inputs, groups = self.window.core.idx.ui.loaders.setup_loader_config()
|
133
|
+
|
134
|
+
for loader in inputs:
|
135
|
+
for k in inputs[loader]:
|
136
|
+
self.window.ui.nodes["dialog.url.loader.config." + loader + "." + k] = inputs[loader][k]
|
137
|
+
for loader in groups:
|
138
|
+
self.window.ui.nodes["dialog.url.loader.config_group"][loader] = groups[loader]
|
139
|
+
params_layout.addWidget(self.window.ui.nodes["dialog.url.loader.config_group"][loader])
|
140
|
+
self.window.ui.nodes["dialog.url.loader.config_group"][loader].hide() # hide on start
|
141
|
+
params_layout.addWidget(self.window.ui.nodes["dialog.url.config.help"], alignment=Qt.AlignCenter)
|
142
|
+
|
143
|
+
# stretch
|
144
|
+
params_layout.addStretch(1)
|
145
|
+
|
146
|
+
self.params_widget = QWidget()
|
147
|
+
self.params_widget.setLayout(params_layout)
|
148
|
+
self.params_scroll.setWidget(self.params_widget)
|
149
|
+
|
150
|
+
# resize
|
151
|
+
self.params_scroll.setWidgetResizable(True)
|
152
|
+
self.params_scroll.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
|
153
|
+
|
154
|
+
# -----------------
|
52
155
|
|
53
156
|
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'])
|
157
|
+
#layout.addWidget(self.window.ui.nodes['dialog.url.label'])
|
158
|
+
#layout.addWidget(self.input)
|
159
|
+
#layout.addWidget(self.window.ui.nodes['dialog.url.tip'])
|
160
|
+
layout.addWidget(self.window.ui.nodes['dialog.url.loader.label'])
|
161
|
+
layout.addWidget(self.window.ui.nodes['dialog.url.loader'])
|
162
|
+
layout.addWidget(self.params_scroll)
|
57
163
|
layout.addLayout(bottom)
|
58
164
|
|
165
|
+
# defaults
|
166
|
+
self.window.ui.nodes["dialog.url.loader"].set_value("webpage")
|
167
|
+
|
59
168
|
self.setLayout(layout)
|
169
|
+
|
170
|
+
self.initialized = True
|
171
|
+
|
172
|
+
def hook_loader_change(self, key, value, caller, *args, **kwargs):
|
173
|
+
"""
|
174
|
+
Hook: on loader change
|
175
|
+
|
176
|
+
:param key: Option key
|
177
|
+
:param value: Option value
|
178
|
+
:param caller: Caller
|
179
|
+
:param args: Args
|
180
|
+
:param kwargs: Kwargs
|
181
|
+
"""
|
182
|
+
# hide/show options
|
183
|
+
for loader in self.window.ui.nodes["dialog.url.loader.option_group"]:
|
184
|
+
self.window.ui.nodes["dialog.url.loader.option_group"][loader].hide()
|
185
|
+
if value in self.window.ui.nodes["dialog.url.loader.option_group"]:
|
186
|
+
self.window.ui.nodes["dialog.url.loader.option_group"][value].show()
|
187
|
+
|
188
|
+
# show/hide label if options are available
|
189
|
+
self.window.ui.nodes["dialog.url.options.label"].hide()
|
190
|
+
if value in self.window.ui.nodes["dialog.url.loader.option_group"]:
|
191
|
+
self.window.ui.nodes["dialog.url.options.label"].show()
|
192
|
+
|
193
|
+
# hide/show config
|
194
|
+
for loader in self.window.ui.nodes["dialog.url.loader.config_group"]:
|
195
|
+
self.window.ui.nodes["dialog.url.loader.config_group"][loader].hide()
|
196
|
+
if value in self.window.ui.nodes["dialog.url.loader.config_group"]:
|
197
|
+
self.window.ui.nodes["dialog.url.loader.config_group"][value].show()
|
198
|
+
|
199
|
+
# show/hide label if config are available
|
200
|
+
self.window.ui.nodes["dialog.url.config.label"].hide()
|
201
|
+
self.window.ui.nodes["dialog.url.config.help"].hide()
|
202
|
+
if value in self.window.ui.nodes["dialog.url.loader.config_group"]:
|
203
|
+
self.window.ui.nodes["dialog.url.config.label"].show()
|
204
|
+
self.window.ui.nodes["dialog.url.config.help"].show()
|
205
|
+
|
206
|
+
self.params_widget.adjustSize()
|
207
|
+
self.params_scroll.update()
|
@@ -6,11 +6,12 @@
|
|
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.
|
9
|
+
# Updated Date: 2024.12.16 01:00:00 #
|
10
10
|
# ================================================== #
|
11
|
+
|
11
12
|
from PySide6.QtCore import Qt
|
12
13
|
from PySide6.QtGui import QIcon
|
13
|
-
from PySide6.QtWidgets import QCheckBox, QWidget, QVBoxLayout
|
14
|
+
from PySide6.QtWidgets import QCheckBox, QWidget, QVBoxLayout, QFrame
|
14
15
|
|
15
16
|
import pygpt_net.icons_rc
|
16
17
|
|
@@ -105,3 +106,15 @@ class CollapsedGroup(QWidget):
|
|
105
106
|
:param option: option widget
|
106
107
|
"""
|
107
108
|
self.options.addWidget(option)
|
109
|
+
|
110
|
+
class QHLine(QFrame):
|
111
|
+
def __init__(self):
|
112
|
+
super(QHLine, self).__init__()
|
113
|
+
self.setFrameShape(QFrame.HLine)
|
114
|
+
self.setFrameShadow(QFrame.Sunken)
|
115
|
+
|
116
|
+
class QVLine(QFrame):
|
117
|
+
def __init__(self):
|
118
|
+
super(QVLine, self).__init__()
|
119
|
+
self.setFrameShape(QFrame.VLine)
|
120
|
+
self.setFrameShadow(QFrame.Sunken)
|
@@ -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.
|
9
|
+
# Updated Date: 2024.12.16 01:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import datetime
|
@@ -14,6 +14,7 @@ import datetime
|
|
14
14
|
from PySide6 import QtWidgets, QtCore, QtGui
|
15
15
|
from PySide6.QtGui import QAction, QIcon, QColor, QPixmap, QStandardItem
|
16
16
|
from PySide6.QtWidgets import QMenu
|
17
|
+
from overrides import overrides
|
17
18
|
|
18
19
|
from pygpt_net.ui.widget.lists.base import BaseList
|
19
20
|
from pygpt_net.utils import trans
|
@@ -31,13 +32,13 @@ class ContextList(BaseList):
|
|
31
32
|
super(ContextList, self).__init__(window)
|
32
33
|
self.window = window
|
33
34
|
self.id = id
|
34
|
-
self.clicked.connect(self.click)
|
35
35
|
self.expanded_items = set()
|
36
36
|
self.setItemDelegate(ImportantItemDelegate())
|
37
37
|
|
38
|
+
|
38
39
|
def click(self, index):
|
39
40
|
"""
|
40
|
-
Click event
|
41
|
+
Click event (override, connected in BaseList class)
|
41
42
|
|
42
43
|
:param index: index
|
43
44
|
"""
|
@@ -49,8 +50,10 @@ class ContextList(BaseList):
|
|
49
50
|
self.window.controller.ctx.set_group(item.id)
|
50
51
|
if self.window.ui.nodes['ctx.list'].isExpanded(index):
|
51
52
|
self.expanded_items.discard(item.id)
|
53
|
+
self.window.ui.nodes['ctx.list'].collapse(index)
|
52
54
|
else:
|
53
55
|
self.expanded_items.add(item.id)
|
56
|
+
self.window.ui.nodes['ctx.list'].expand(index)
|
54
57
|
else:
|
55
58
|
self.window.controller.ctx.select_by_id(item.id)
|
56
59
|
else:
|
@@ -76,7 +79,7 @@ class ContextList(BaseList):
|
|
76
79
|
|
77
80
|
:param index: index
|
78
81
|
"""
|
79
|
-
|
82
|
+
print("dblclick")
|
80
83
|
|
81
84
|
def mousePressEvent(self, event):
|
82
85
|
"""
|
@@ -407,20 +410,28 @@ class ImportantItemDelegate(QtWidgets.QStyledItemDelegate):
|
|
407
410
|
label = 0
|
408
411
|
is_important = False
|
409
412
|
is_attachment = False
|
413
|
+
is_group = False
|
414
|
+
in_group = False
|
415
|
+
|
410
416
|
if "label" in data:
|
411
417
|
label = data["label"]
|
412
418
|
if "is_important" in data and data["is_important"]:
|
413
419
|
is_important = True
|
414
420
|
if "is_attachment" in data and data["is_attachment"]:
|
415
421
|
is_attachment = True
|
422
|
+
if "is_group" in data and data["is_group"]:
|
423
|
+
is_group = True
|
424
|
+
if "in_group" in data and data["in_group"]:
|
425
|
+
in_group = True
|
416
426
|
|
417
427
|
painter.save()
|
418
428
|
|
419
429
|
if is_attachment:
|
420
430
|
icon = QtGui.QIcon(":/icons/attachment.svg")
|
421
431
|
icon_size = option.decorationSize or QtCore.QSize(16, 16)
|
432
|
+
icon_pos = option.rect.right() - icon_size.width()
|
422
433
|
icon_rect = QtCore.QRect(
|
423
|
-
|
434
|
+
icon_pos,
|
424
435
|
option.rect.top() + (option.rect.height() - icon_size.height()) / 2,
|
425
436
|
icon_size.width(),
|
426
437
|
icon_size.height()
|
@@ -447,8 +458,6 @@ class ImportantItemDelegate(QtWidgets.QStyledItemDelegate):
|
|
447
458
|
)
|
448
459
|
painter.drawRect(square_rect)
|
449
460
|
|
450
|
-
#label = label - 10 # remove pin status
|
451
|
-
|
452
461
|
# label (0-9)
|
453
462
|
if label > 0:
|
454
463
|
color = self.get_color_for_status(label)
|
@@ -495,6 +504,7 @@ class GroupItem(QStandardItem):
|
|
495
504
|
self.name = name
|
496
505
|
self.isFolder = True
|
497
506
|
self.isPinned = False
|
507
|
+
self.hasAttachments = False
|
498
508
|
self.dt = None
|
499
509
|
|
500
510
|
class Item(QStandardItem):
|
@@ -507,12 +517,16 @@ class Item(QStandardItem):
|
|
507
517
|
self.dt = None
|
508
518
|
|
509
519
|
class SectionItem(QStandardItem):
|
510
|
-
def __init__(self, title):
|
520
|
+
def __init__(self, title, group: bool = False):
|
511
521
|
super().__init__(title)
|
512
522
|
self.title = title
|
523
|
+
self.group = group
|
513
524
|
self.setSelectable(False)
|
514
525
|
self.setEnabled(False)
|
515
|
-
self.
|
526
|
+
if self.group:
|
527
|
+
self.setTextAlignment(QtCore.Qt.AlignLeft)
|
528
|
+
else:
|
529
|
+
self.setTextAlignment(QtCore.Qt.AlignRight)
|
516
530
|
font = self.font()
|
517
531
|
font.setBold(True)
|
518
532
|
self.setFont(font)
|
pygpt_net/utils.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pygpt-net
|
3
|
-
Version: 2.4.
|
3
|
+
Version: 2.4.45
|
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
|
[](https://snapcraft.io/pygpt)
|
94
94
|
|
95
|
-
Release: **2.4.
|
95
|
+
Release: **2.4.45** | build: **2024.12.16** | Python: **>=3.10, <3.12**
|
96
96
|
|
97
97
|
> Official website: https://pygpt.net | Documentation: https://pygpt.readthedocs.io
|
98
98
|
>
|
@@ -875,6 +875,8 @@ You can use your own files (for example, to analyze them) during any conversatio
|
|
875
875
|
|
876
876
|
**PyGPT** makes it simple for users to upload files and send them to the model for tasks like analysis, similar to attaching files in `ChatGPT`. There's a separate `Attachments` tab next to the text input area specifically for managing file uploads.
|
877
877
|
|
878
|
+
**Tip: Attachments uploaded in group are available in all contexts in group**.
|
879
|
+
|
878
880
|

|
879
881
|
|
880
882
|
You can use attachments to provide additional context to the conversation. Uploaded files will be converted into text using loaders from LlamaIndex, and then embedded into the vector store. You can upload any file format supported by the application through LlamaIndex. Supported formats include:
|
@@ -3350,8 +3352,10 @@ Allowed additional keyword arguments for built-in data loaders (Web and external
|
|
3350
3352
|
|
3351
3353
|
**SQL Database** (web_database)
|
3352
3354
|
|
3353
|
-
- `engine` - str, default: `None`
|
3354
3355
|
- `uri` - str, default: `None`
|
3356
|
+
|
3357
|
+
You can provide a single URI in the form of: `{scheme}://{user}:{password}@{host}:{port}/{dbname}`, or you can provide each field manually:
|
3358
|
+
|
3355
3359
|
- `scheme` - str, default: `None`
|
3356
3360
|
- `host` - str, default: `None`
|
3357
3361
|
- `port` - str, default: `None`
|
@@ -4024,6 +4028,21 @@ may consume additional tokens that are not displayed in the main window.
|
|
4024
4028
|
|
4025
4029
|
## Recent changes:
|
4026
4030
|
|
4031
|
+
**2.4.45 (2024-12-16)**
|
4032
|
+
|
4033
|
+
- Enhanced web data loaders UI.
|
4034
|
+
|
4035
|
+
**2.4.44 (2024-12-16)**
|
4036
|
+
|
4037
|
+
- Enhanced web data loaders.
|
4038
|
+
- Web loaders have been added to attachments, allowing external web content to be attached to context via the "+Web" button in the Attachments tab.
|
4039
|
+
- Improved handling of attachments in groups and added an attachment icon when a group contains attachments.
|
4040
|
+
|
4041
|
+
**2.4.43 (2024-12-15)**
|
4042
|
+
|
4043
|
+
- Fix: Bug on attachment upload.
|
4044
|
+
- Added: Attachments uploaded in groups are now available for all contexts in the group (beta).
|
4045
|
+
|
4027
4046
|
**2.4.42 (2024-12-15)**
|
4028
4047
|
|
4029
4048
|
- Added Mailer plugin, which allows sending and retrieving emails from the server, and reading them. It currently supports only SMTP.
|