pygpt-net 2.4.30__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.
- CHANGELOG.md +24 -0
- README.md +46 -5
- pygpt_net/CHANGELOG.txt +24 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/access/__init__.py +5 -5
- pygpt_net/controller/access/control.py +3 -2
- pygpt_net/controller/attachment.py +67 -1
- pygpt_net/controller/audio/__init__.py +34 -6
- pygpt_net/controller/chat/__init__.py +3 -1
- pygpt_net/controller/chat/attachment.py +239 -37
- pygpt_net/controller/chat/audio.py +99 -0
- pygpt_net/controller/chat/input.py +10 -3
- pygpt_net/controller/chat/output.py +4 -1
- pygpt_net/controller/chat/text.py +7 -3
- pygpt_net/controller/dialogs/confirm.py +17 -1
- pygpt_net/controller/lang/custom.py +3 -1
- pygpt_net/controller/mode.py +2 -1
- pygpt_net/controller/presets/editor.py +11 -2
- pygpt_net/core/access/voice.py +2 -2
- pygpt_net/core/agents/legacy.py +3 -1
- pygpt_net/core/attachments/__init__.py +11 -7
- pygpt_net/core/attachments/context.py +226 -44
- pygpt_net/core/{audio.py → audio/__init__.py} +1 -1
- pygpt_net/core/audio/context.py +34 -0
- pygpt_net/core/bridge/context.py +29 -1
- pygpt_net/core/ctx/__init__.py +4 -1
- pygpt_net/core/db/__init__.py +4 -2
- pygpt_net/core/debug/attachments.py +3 -1
- pygpt_net/core/debug/context.py +5 -1
- pygpt_net/core/debug/presets.py +3 -1
- pygpt_net/core/events/event.py +2 -1
- pygpt_net/core/experts/__init__.py +3 -1
- pygpt_net/core/idx/chat.py +28 -6
- pygpt_net/core/idx/indexing.py +123 -15
- pygpt_net/core/modes.py +3 -1
- pygpt_net/core/presets.py +13 -2
- pygpt_net/core/render/markdown/pid.py +2 -1
- pygpt_net/core/render/plain/pid.py +2 -1
- pygpt_net/core/render/web/body.py +34 -12
- pygpt_net/core/render/web/pid.py +2 -1
- pygpt_net/core/render/web/renderer.py +8 -3
- pygpt_net/core/tokens.py +4 -2
- pygpt_net/core/types/mode.py +2 -1
- pygpt_net/data/config/config.json +5 -3
- pygpt_net/data/config/models.json +190 -5
- pygpt_net/data/config/modes.json +11 -5
- pygpt_net/data/config/presets/current.audio.json +34 -0
- pygpt_net/data/config/settings.json +15 -1
- pygpt_net/data/css/web.css +70 -0
- pygpt_net/data/css/web.dark.css +4 -1
- pygpt_net/data/css/web.light.css +1 -1
- pygpt_net/data/locale/locale.de.ini +26 -13
- pygpt_net/data/locale/locale.en.ini +61 -46
- pygpt_net/data/locale/locale.es.ini +26 -13
- pygpt_net/data/locale/locale.fr.ini +28 -15
- pygpt_net/data/locale/locale.it.ini +26 -13
- pygpt_net/data/locale/locale.pl.ini +30 -17
- pygpt_net/data/locale/locale.uk.ini +26 -13
- pygpt_net/data/locale/locale.zh.ini +33 -20
- pygpt_net/data/locale/plugin.cmd_files.de.ini +4 -4
- pygpt_net/data/locale/plugin.cmd_files.en.ini +4 -4
- pygpt_net/data/locale/plugin.cmd_files.es.ini +4 -4
- pygpt_net/data/locale/plugin.cmd_files.fr.ini +4 -4
- pygpt_net/data/locale/plugin.cmd_files.it.ini +4 -4
- pygpt_net/data/locale/plugin.cmd_files.pl.ini +4 -4
- pygpt_net/data/locale/plugin.cmd_files.uk.ini +4 -4
- pygpt_net/data/locale/plugin.cmd_files.zh.ini +4 -4
- pygpt_net/data/locale/plugin.cmd_web.de.ini +5 -5
- pygpt_net/data/locale/plugin.cmd_web.en.ini +5 -5
- pygpt_net/data/locale/plugin.cmd_web.es.ini +5 -5
- pygpt_net/data/locale/plugin.cmd_web.fr.ini +5 -5
- pygpt_net/data/locale/plugin.cmd_web.it.ini +5 -5
- pygpt_net/data/locale/plugin.cmd_web.pl.ini +5 -5
- pygpt_net/data/locale/plugin.cmd_web.uk.ini +5 -5
- pygpt_net/data/locale/plugin.cmd_web.zh.ini +5 -5
- pygpt_net/data/locale/plugin.idx_llama_index.de.ini +12 -12
- pygpt_net/data/locale/plugin.idx_llama_index.en.ini +12 -12
- pygpt_net/data/locale/plugin.idx_llama_index.es.ini +12 -12
- pygpt_net/data/locale/plugin.idx_llama_index.fr.ini +12 -12
- pygpt_net/data/locale/plugin.idx_llama_index.it.ini +12 -12
- pygpt_net/data/locale/plugin.idx_llama_index.pl.ini +12 -12
- pygpt_net/data/locale/plugin.idx_llama_index.uk.ini +12 -12
- pygpt_net/data/locale/plugin.idx_llama_index.zh.ini +12 -12
- pygpt_net/item/attachment.py +9 -1
- pygpt_net/item/ctx.py +9 -1
- pygpt_net/item/preset.py +5 -1
- pygpt_net/launcher.py +3 -1
- pygpt_net/migrations/Version20241126170000.py +28 -0
- pygpt_net/migrations/__init__.py +3 -1
- pygpt_net/plugin/audio_input/__init__.py +11 -1
- pygpt_net/plugin/audio_input/worker.py +9 -1
- pygpt_net/plugin/audio_output/__init__.py +37 -7
- pygpt_net/plugin/audio_output/worker.py +38 -41
- pygpt_net/plugin/cmd_code_interpreter/runner.py +2 -2
- pygpt_net/plugin/cmd_mouse_control/__init__.py +4 -2
- pygpt_net/plugin/openai_dalle/__init__.py +3 -1
- pygpt_net/plugin/openai_vision/__init__.py +3 -1
- pygpt_net/provider/core/attachment/json_file.py +4 -1
- pygpt_net/provider/core/config/patch.py +16 -0
- pygpt_net/provider/core/ctx/db_sqlite/storage.py +14 -4
- pygpt_net/provider/core/ctx/db_sqlite/utils.py +19 -2
- pygpt_net/provider/core/model/patch.py +7 -1
- pygpt_net/provider/core/preset/json_file.py +5 -1
- pygpt_net/provider/gpt/__init__.py +14 -2
- pygpt_net/provider/gpt/audio.py +63 -0
- pygpt_net/provider/gpt/chat.py +76 -44
- pygpt_net/provider/gpt/utils.py +27 -0
- pygpt_net/provider/gpt/vision.py +37 -15
- pygpt_net/provider/loaders/base.py +10 -1
- pygpt_net/provider/loaders/web_yt.py +19 -1
- pygpt_net/tools/image_viewer/ui/dialogs.py +3 -1
- pygpt_net/ui/dialog/preset.py +3 -1
- pygpt_net/ui/dialog/url.py +29 -0
- pygpt_net/ui/dialogs.py +5 -1
- pygpt_net/ui/layout/chat/attachments.py +42 -6
- pygpt_net/ui/layout/chat/attachments_ctx.py +14 -4
- pygpt_net/ui/layout/chat/attachments_uploaded.py +8 -4
- pygpt_net/ui/widget/dialog/url.py +59 -0
- pygpt_net/ui/widget/lists/attachment.py +22 -17
- pygpt_net/ui/widget/lists/attachment_ctx.py +65 -3
- pygpt_net/ui/widget/textarea/url.py +43 -0
- {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.34.dist-info}/METADATA +48 -7
- {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.34.dist-info}/RECORD +126 -117
- {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.34.dist-info}/LICENSE +0 -0
- {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.34.dist-info}/WHEEL +0 -0
- {pygpt_net-2.4.30.dist-info → pygpt_net-2.4.34.dist-info}/entry_points.txt +0 -0
@@ -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.
|
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,12 +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
|
+
|
54
|
+
buttons.addWidget(self.setup_auto_index())
|
45
55
|
buttons.addWidget(self.setup_send_clear())
|
46
56
|
buttons.addWidget(self.setup_capture_clear())
|
57
|
+
buttons.addStretch()
|
47
58
|
|
48
59
|
self.window.ui.nodes['tip.input.attachments'] = HelpLabel(trans('tip.input.attachments'), self.window)
|
49
60
|
|
@@ -88,15 +99,34 @@ class Attachments:
|
|
88
99
|
|
89
100
|
return widget
|
90
101
|
|
102
|
+
def setup_auto_index(self) -> QWidget:
|
103
|
+
"""
|
104
|
+
Setup auto index checkbox
|
105
|
+
|
106
|
+
:return: QWidget
|
107
|
+
"""
|
108
|
+
layout = QHBoxLayout()
|
109
|
+
layout.setContentsMargins(0, 0, 0, 0)
|
110
|
+
layout.setAlignment(Qt.AlignCenter)
|
111
|
+
layout.addWidget(self.window.ui.nodes['attachments.auto_index'])
|
112
|
+
|
113
|
+
widget = QWidget()
|
114
|
+
widget.setLayout(layout)
|
115
|
+
|
116
|
+
return widget
|
117
|
+
|
91
118
|
def setup_buttons(self):
|
92
119
|
"""
|
93
120
|
Setup buttons
|
94
121
|
"""
|
95
|
-
self.window.ui.nodes['attachments.btn.add'] = QPushButton(trans('attachments.btn.add'))
|
96
|
-
self.window.ui.nodes['attachments.btn.
|
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'))
|
97
125
|
|
98
126
|
self.window.ui.nodes['attachments.btn.add'].clicked.connect(
|
99
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())
|
100
130
|
self.window.ui.nodes['attachments.btn.clear'].clicked.connect(
|
101
131
|
lambda: self.window.controller.attachment.clear(remove_local=True))
|
102
132
|
|
@@ -110,6 +140,11 @@ class Attachments:
|
|
110
140
|
lambda: self.window.controller.attachment.toggle_capture_clear(
|
111
141
|
self.window.ui.nodes['attachments.capture_clear'].isChecked()))
|
112
142
|
|
143
|
+
self.window.ui.nodes['attachments.auto_index'] = QCheckBox(trans('attachments.auto_index'))
|
144
|
+
self.window.ui.nodes['attachments.auto_index'].stateChanged.connect(
|
145
|
+
lambda: self.window.controller.attachment.toggle_auto_index(
|
146
|
+
self.window.ui.nodes['attachments.auto_index'].isChecked()))
|
147
|
+
|
113
148
|
def setup_attachments(self):
|
114
149
|
"""
|
115
150
|
Setup attachments list
|
@@ -144,8 +179,9 @@ class Attachments:
|
|
144
179
|
for id in data:
|
145
180
|
path = data[id].path
|
146
181
|
size = ""
|
147
|
-
if
|
148
|
-
|
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))
|
149
185
|
ctx_str = ""
|
150
186
|
if data[id].ctx:
|
151
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.
|
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
|
)
|
@@ -105,11 +106,12 @@ class AttachmentsCtx:
|
|
105
106
|
:param parent: parent widget
|
106
107
|
:return: QStandardItemModel
|
107
108
|
"""
|
108
|
-
model = QStandardItemModel(0,
|
109
|
+
model = QStandardItemModel(0, 5, parent)
|
109
110
|
model.setHeaderData(0, Qt.Horizontal, trans('attachments.header.name'))
|
110
111
|
model.setHeaderData(1, Qt.Horizontal, trans('attachments.header.path'))
|
111
112
|
model.setHeaderData(2, Qt.Horizontal, trans('attachments.header.size'))
|
112
113
|
model.setHeaderData(3, Qt.Horizontal, trans('attachments.header.length'))
|
114
|
+
model.setHeaderData(4, Qt.Horizontal, trans('attachments.header.idx'))
|
113
115
|
return model
|
114
116
|
|
115
117
|
def update(self, data):
|
@@ -121,6 +123,7 @@ class AttachmentsCtx:
|
|
121
123
|
self.window.ui.models[self.id].removeRows(0, self.window.ui.models[self.id].rowCount())
|
122
124
|
i = 0
|
123
125
|
for item in data:
|
126
|
+
indexed = False
|
124
127
|
name = "No name"
|
125
128
|
if 'name' in item:
|
126
129
|
name = item['name']
|
@@ -136,6 +139,12 @@ class AttachmentsCtx:
|
|
136
139
|
length = str(item['length'])
|
137
140
|
if 'tokens' in item:
|
138
141
|
length += ' / ~' + str(item['tokens'])
|
142
|
+
if 'indexed' in item and item['indexed']:
|
143
|
+
indexed = True
|
144
|
+
|
145
|
+
idx_str = ""
|
146
|
+
if indexed:
|
147
|
+
idx_str = trans("attachments.ctx.indexed")
|
139
148
|
|
140
149
|
if os.path.exists(path):
|
141
150
|
size = self.window.core.filesystem.sizeof_fmt(os.path.getsize(path))
|
@@ -149,4 +158,5 @@ class AttachmentsCtx:
|
|
149
158
|
self.window.ui.models[self.id].setData(self.window.ui.models[self.id].index(i, 1), path)
|
150
159
|
self.window.ui.models[self.id].setData(self.window.ui.models[self.id].index(i, 2), size)
|
151
160
|
self.window.ui.models[self.id].setData(self.window.ui.models[self.id].index(i, 3), length)
|
161
|
+
self.window.ui.models[self.id].setData(self.window.ui.models[self.id].index(i, 4), idx_str)
|
152
162
|
i += 1
|
@@ -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'] =
|
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.
|
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
|
-
|
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
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
if
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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.
|
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)
|
@@ -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.
|
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
|
@@ -66,7 +66,7 @@ Requires-Dist: llama-index-vector-stores-pinecone (>=0.1.3,<0.2.0)
|
|
66
66
|
Requires-Dist: llama-index-vector-stores-redis (>=0.1.2,<0.2.0)
|
67
67
|
Requires-Dist: mss (>=9.0.2,<10.0.0)
|
68
68
|
Requires-Dist: nbconvert (>=7.16.1,<8.0.0)
|
69
|
-
Requires-Dist: openai (>=1.
|
69
|
+
Requires-Dist: openai (>=1.55.1,<1.60.0)
|
70
70
|
Requires-Dist: opencv-python (>=4.9.0.80,<5.0.0.0)
|
71
71
|
Requires-Dist: packaging (>=23.2,<24.0)
|
72
72
|
Requires-Dist: pandas (>=2.2.0,<3.0.0)
|
@@ -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.34** | 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
|
-
##
|
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
|
-
###
|
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
|
-
|
280
|
+
### Install with Poetry
|
281
281
|
|
282
282
|
1. Clone git repository or download .zip file:
|
283
283
|
|
@@ -446,7 +446,7 @@ This mode in **PyGPT** mirrors `ChatGPT`, allowing you to chat with models such
|
|
446
446
|
|
447
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.
|
448
448
|
|
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 `
|
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).
|
450
450
|
|
451
451
|

|
452
452
|
|
@@ -464,6 +464,17 @@ Plugin allows you to generate images in Chat mode:
|
|
464
464
|
|
465
465
|

|
466
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
|
+
|
467
478
|
## Completion
|
468
479
|
|
469
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`.
|
@@ -1187,6 +1198,10 @@ The content from the uploaded attachments will be used in the current conversati
|
|
1187
1198
|
|
1188
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.
|
1189
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
|
+
|
1190
1205
|
## Files (download, code generation)
|
1191
1206
|
|
1192
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.
|
@@ -1655,6 +1670,8 @@ Python code to a file, which the `Code Interpreter` can execute it and return it
|
|
1655
1670
|
- `Files I/O` - provides access to the local filesystem, enabling GPT to read and write files,
|
1656
1671
|
as well as list and create directories.
|
1657
1672
|
|
1673
|
+
- `System (OS)` - allows you to create and execute custom commands on your system.
|
1674
|
+
|
1658
1675
|
- `Mouse and Keyboard` - provides the ability to control the mouse and keyboard by the model.
|
1659
1676
|
|
1660
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.
|
@@ -3742,6 +3759,30 @@ may consume additional tokens that are not displayed in the main window.
|
|
3742
3759
|
|
3743
3760
|
## Recent changes:
|
3744
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
|
+
|
3745
3786
|
**2.4.30 (2024-11-25)**
|
3746
3787
|
|
3747
3788
|
- Added instruction to model about mapped data directory in both legacy and IPython code interepreter.
|