pygpt-net 2.7.4__py3-none-any.whl → 2.7.6__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.
- pygpt_net/CHANGELOG.txt +15 -0
- pygpt_net/__init__.py +4 -4
- pygpt_net/app_core.py +4 -2
- pygpt_net/controller/__init__.py +5 -1
- pygpt_net/controller/assistant/assistant.py +1 -4
- pygpt_net/controller/assistant/batch.py +5 -504
- pygpt_net/controller/assistant/editor.py +5 -5
- pygpt_net/controller/assistant/files.py +16 -16
- pygpt_net/controller/chat/handler/google_stream.py +307 -1
- pygpt_net/controller/chat/handler/worker.py +10 -25
- pygpt_net/controller/chat/handler/xai_stream.py +621 -52
- pygpt_net/controller/chat/image.py +2 -2
- pygpt_net/controller/debug/fixtures.py +3 -2
- pygpt_net/controller/dialogs/confirm.py +73 -101
- pygpt_net/controller/files/files.py +65 -4
- pygpt_net/controller/lang/mapping.py +9 -9
- pygpt_net/controller/painter/capture.py +50 -1
- pygpt_net/controller/presets/presets.py +2 -1
- pygpt_net/controller/remote_store/__init__.py +12 -0
- pygpt_net/{provider/core/assistant_file/db_sqlite → controller/remote_store/google}/__init__.py +2 -2
- pygpt_net/controller/remote_store/google/batch.py +402 -0
- pygpt_net/controller/remote_store/google/store.py +615 -0
- pygpt_net/controller/remote_store/openai/__init__.py +12 -0
- pygpt_net/controller/remote_store/openai/batch.py +524 -0
- pygpt_net/controller/{assistant → remote_store/openai}/store.py +63 -60
- pygpt_net/controller/remote_store/remote_store.py +35 -0
- pygpt_net/controller/ui/ui.py +20 -1
- pygpt_net/core/assistants/assistants.py +3 -15
- pygpt_net/core/db/database.py +5 -3
- pygpt_net/core/filesystem/url.py +4 -1
- pygpt_net/core/locale/placeholder.py +35 -0
- pygpt_net/core/remote_store/__init__.py +12 -0
- pygpt_net/core/remote_store/google/__init__.py +11 -0
- pygpt_net/core/remote_store/google/files.py +224 -0
- pygpt_net/core/remote_store/google/store.py +248 -0
- pygpt_net/core/remote_store/openai/__init__.py +11 -0
- pygpt_net/core/{assistants → remote_store/openai}/files.py +26 -19
- pygpt_net/core/{assistants → remote_store/openai}/store.py +32 -15
- pygpt_net/core/remote_store/remote_store.py +24 -0
- pygpt_net/core/render/web/body.py +3 -2
- pygpt_net/core/types/chunk.py +27 -0
- pygpt_net/data/config/config.json +8 -4
- pygpt_net/data/config/models.json +77 -3
- pygpt_net/data/config/settings.json +45 -0
- pygpt_net/data/js/app/template.js +1 -1
- pygpt_net/data/js/app.min.js +2 -2
- pygpt_net/data/locale/locale.de.ini +44 -41
- pygpt_net/data/locale/locale.en.ini +56 -43
- pygpt_net/data/locale/locale.es.ini +44 -41
- pygpt_net/data/locale/locale.fr.ini +44 -41
- pygpt_net/data/locale/locale.it.ini +44 -41
- pygpt_net/data/locale/locale.pl.ini +45 -42
- pygpt_net/data/locale/locale.uk.ini +44 -41
- pygpt_net/data/locale/locale.zh.ini +44 -41
- pygpt_net/data/locale/plugin.cmd_history.de.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.en.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.es.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.fr.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.it.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.pl.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.uk.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_history.zh.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_mouse_control.en.ini +14 -0
- pygpt_net/data/locale/plugin.cmd_web.de.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.en.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.es.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.fr.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.it.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.pl.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.uk.ini +1 -1
- pygpt_net/data/locale/plugin.cmd_web.zh.ini +1 -1
- pygpt_net/data/locale/plugin.idx_llama_index.de.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.en.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.es.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.fr.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.it.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.pl.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.uk.ini +2 -2
- pygpt_net/data/locale/plugin.idx_llama_index.zh.ini +2 -2
- pygpt_net/item/assistant.py +1 -211
- pygpt_net/item/ctx.py +3 -3
- pygpt_net/item/store.py +238 -0
- pygpt_net/js_rc.py +2449 -2447
- pygpt_net/migrations/Version20260102190000.py +35 -0
- pygpt_net/migrations/__init__.py +3 -1
- pygpt_net/plugin/cmd_mouse_control/config.py +471 -1
- pygpt_net/plugin/cmd_mouse_control/plugin.py +487 -22
- pygpt_net/plugin/cmd_mouse_control/worker.py +464 -87
- pygpt_net/plugin/cmd_mouse_control/worker_sandbox.py +729 -0
- pygpt_net/plugin/idx_llama_index/config.py +2 -2
- pygpt_net/provider/api/anthropic/__init__.py +10 -8
- pygpt_net/provider/api/google/__init__.py +21 -58
- pygpt_net/provider/api/google/chat.py +545 -129
- pygpt_net/provider/api/google/computer.py +190 -0
- pygpt_net/provider/api/google/realtime/realtime.py +2 -2
- pygpt_net/provider/api/google/remote_tools.py +93 -0
- pygpt_net/provider/api/google/store.py +546 -0
- pygpt_net/provider/api/google/worker/__init__.py +0 -0
- pygpt_net/provider/api/google/worker/importer.py +392 -0
- pygpt_net/provider/api/openai/__init__.py +7 -3
- pygpt_net/provider/api/openai/computer.py +10 -1
- pygpt_net/provider/api/openai/responses.py +0 -0
- pygpt_net/provider/api/openai/store.py +6 -6
- pygpt_net/provider/api/openai/worker/importer.py +24 -24
- pygpt_net/provider/api/x_ai/__init__.py +10 -9
- pygpt_net/provider/api/x_ai/chat.py +272 -102
- pygpt_net/provider/core/config/patch.py +16 -1
- pygpt_net/provider/core/config/patches/patch_before_2_6_42.py +3 -3
- pygpt_net/provider/core/model/patch.py +17 -3
- pygpt_net/provider/core/preset/json_file.py +13 -7
- pygpt_net/provider/core/{assistant_file → remote_file}/__init__.py +1 -1
- pygpt_net/provider/core/{assistant_file → remote_file}/base.py +9 -9
- pygpt_net/provider/core/remote_file/db_sqlite/__init__.py +12 -0
- pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/patch.py +1 -1
- pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/provider.py +23 -20
- pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/storage.py +35 -27
- pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/utils.py +5 -4
- pygpt_net/provider/core/{assistant_store → remote_store}/__init__.py +1 -1
- pygpt_net/provider/core/{assistant_store → remote_store}/base.py +10 -10
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/__init__.py +1 -1
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/patch.py +1 -1
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/provider.py +16 -15
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/storage.py +30 -23
- pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/utils.py +5 -4
- pygpt_net/provider/core/{assistant_store → remote_store}/json_file.py +9 -9
- pygpt_net/provider/llms/google.py +2 -2
- pygpt_net/tools/image_viewer/ui/dialogs.py +298 -12
- pygpt_net/tools/text_editor/ui/widgets.py +5 -1
- pygpt_net/ui/base/config_dialog.py +3 -2
- pygpt_net/ui/base/context_menu.py +44 -1
- pygpt_net/ui/dialog/assistant.py +3 -3
- pygpt_net/ui/dialog/plugins.py +3 -1
- pygpt_net/ui/dialog/remote_store_google.py +539 -0
- pygpt_net/ui/dialog/{assistant_store.py → remote_store_openai.py} +95 -95
- pygpt_net/ui/dialogs.py +5 -3
- pygpt_net/ui/layout/chat/attachments_uploaded.py +3 -3
- pygpt_net/ui/layout/toolbox/computer_env.py +26 -8
- pygpt_net/ui/layout/toolbox/indexes.py +22 -19
- pygpt_net/ui/layout/toolbox/model.py +28 -5
- pygpt_net/ui/menu/tools.py +13 -5
- pygpt_net/ui/widget/dialog/remote_store_google.py +56 -0
- pygpt_net/ui/widget/dialog/{assistant_store.py → remote_store_openai.py} +9 -9
- pygpt_net/ui/widget/element/button.py +4 -4
- pygpt_net/ui/widget/image/display.py +25 -8
- pygpt_net/ui/widget/lists/remote_store_google.py +248 -0
- pygpt_net/ui/widget/lists/{assistant_store.py → remote_store_openai.py} +21 -21
- pygpt_net/ui/widget/option/checkbox_list.py +47 -9
- pygpt_net/ui/widget/option/combo.py +39 -3
- pygpt_net/ui/widget/tabs/output.py +9 -1
- pygpt_net/ui/widget/textarea/editor.py +14 -1
- pygpt_net/ui/widget/textarea/input.py +20 -7
- pygpt_net/ui/widget/textarea/notepad.py +24 -1
- pygpt_net/ui/widget/textarea/output.py +23 -1
- pygpt_net/ui/widget/textarea/web.py +16 -1
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/METADATA +41 -2
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/RECORD +158 -132
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/LICENSE +0 -0
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.dist-info}/WHEEL +0 -0
- {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.6.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:
|
|
9
|
+
# Updated Date: 2026.01.02 19:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import copy
|
|
@@ -17,44 +17,47 @@ from PySide6.QtWidgets import QApplication
|
|
|
17
17
|
from PySide6.QtGui import QStandardItem
|
|
18
18
|
from PySide6.QtCore import Qt, QTimer
|
|
19
19
|
|
|
20
|
-
from pygpt_net.item.
|
|
20
|
+
from pygpt_net.item.store import RemoteStoreItem
|
|
21
21
|
from pygpt_net.utils import trans
|
|
22
22
|
|
|
23
|
+
from .batch import Batch
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
|
|
26
|
+
class OpenAIRemoteStore:
|
|
25
27
|
def __init__(self, window=None):
|
|
26
28
|
"""
|
|
27
|
-
|
|
29
|
+
OpenAI vector store editor controller
|
|
28
30
|
|
|
29
31
|
:param window: Window instance
|
|
30
32
|
"""
|
|
31
33
|
self.window = window
|
|
34
|
+
self.batch = Batch(window)
|
|
32
35
|
self.dialog = False
|
|
33
36
|
self.config_initialized = False
|
|
34
37
|
self.current = None
|
|
35
38
|
self.width = 800
|
|
36
39
|
self.height = 500
|
|
37
|
-
self.id = "
|
|
40
|
+
self.id = "remote_store.openai"
|
|
38
41
|
self.options = {
|
|
39
42
|
"id": {
|
|
40
43
|
"type": "text",
|
|
41
|
-
"label": "
|
|
44
|
+
"label": "remote_store.id",
|
|
42
45
|
"read_only": True,
|
|
43
46
|
"value": "",
|
|
44
47
|
},
|
|
45
48
|
"name": {
|
|
46
49
|
"type": "text",
|
|
47
|
-
"label": "
|
|
50
|
+
"label": "remote_store.name",
|
|
48
51
|
"value": "",
|
|
49
52
|
},
|
|
50
53
|
"expire_days": {
|
|
51
54
|
"type": "int",
|
|
52
|
-
"label": "
|
|
55
|
+
"label": "remote_store.expire_days",
|
|
53
56
|
"value": 0,
|
|
54
57
|
},
|
|
55
58
|
"status": {
|
|
56
59
|
"type": "textarea",
|
|
57
|
-
"label": "
|
|
60
|
+
"label": "remote_store.status",
|
|
58
61
|
"read_only": True,
|
|
59
62
|
"value": "",
|
|
60
63
|
},
|
|
@@ -83,7 +86,7 @@ class VectorStore:
|
|
|
83
86
|
def setup(self):
|
|
84
87
|
"""Set up vector store editor"""
|
|
85
88
|
idx = None
|
|
86
|
-
self.window.
|
|
89
|
+
self.window.remote_store_openai.setup(idx) # widget dialog setup
|
|
87
90
|
|
|
88
91
|
def toggle_editor(self):
|
|
89
92
|
"""Toggle vector store editor dialog"""
|
|
@@ -111,7 +114,7 @@ class VectorStore:
|
|
|
111
114
|
self.current = self.window.controller.assistant.editor.get_selected_store_id()
|
|
112
115
|
self.init()
|
|
113
116
|
self.window.ui.dialogs.open(
|
|
114
|
-
"
|
|
117
|
+
"remote_store.openai",
|
|
115
118
|
width=self.width,
|
|
116
119
|
height=self.height,
|
|
117
120
|
)
|
|
@@ -120,7 +123,7 @@ class VectorStore:
|
|
|
120
123
|
def close(self):
|
|
121
124
|
"""Close vector store editor dialog"""
|
|
122
125
|
if self.dialog:
|
|
123
|
-
self.window.ui.dialogs.close('
|
|
126
|
+
self.window.ui.dialogs.close('remote_store.openai')
|
|
124
127
|
self.dialog = False
|
|
125
128
|
|
|
126
129
|
def init(self):
|
|
@@ -133,8 +136,8 @@ class VectorStore:
|
|
|
133
136
|
|
|
134
137
|
# assign store to config dialog fields
|
|
135
138
|
options = copy.deepcopy(self.get_options()) # copy options
|
|
136
|
-
if self.current is not None and self.window.core.
|
|
137
|
-
store = self.window.core.
|
|
139
|
+
if self.current is not None and self.window.core.remote_store.openai.has(self.current):
|
|
140
|
+
store = self.window.core.remote_store.openai.items[self.current]
|
|
138
141
|
data_dict = store.to_dict()
|
|
139
142
|
for key in options:
|
|
140
143
|
if key in data_dict:
|
|
@@ -156,10 +159,10 @@ class VectorStore:
|
|
|
156
159
|
def refresh_status(self):
|
|
157
160
|
"""Reload store status"""
|
|
158
161
|
if self.current is not None: # TODO: reset on profile reload
|
|
159
|
-
if self.window.core.
|
|
162
|
+
if self.window.core.remote_store.openai.has(self.current):
|
|
160
163
|
self.window.update_status(trans('status.sending'))
|
|
161
164
|
QApplication.processEvents()
|
|
162
|
-
store = self.window.core.
|
|
165
|
+
store = self.window.core.remote_store.openai.items[self.current]
|
|
163
166
|
self.refresh_store(store)
|
|
164
167
|
self.window.update_status(trans('status.assistant.saved'))
|
|
165
168
|
self.update() # update stores list in assistant dialog
|
|
@@ -167,7 +170,7 @@ class VectorStore:
|
|
|
167
170
|
|
|
168
171
|
def refresh_store(
|
|
169
172
|
self,
|
|
170
|
-
store:
|
|
173
|
+
store: RemoteStoreItem,
|
|
171
174
|
update: bool = True
|
|
172
175
|
):
|
|
173
176
|
"""
|
|
@@ -177,8 +180,8 @@ class VectorStore:
|
|
|
177
180
|
:param update: update store after refresh
|
|
178
181
|
"""
|
|
179
182
|
# update from API
|
|
180
|
-
self.window.core.
|
|
181
|
-
self.window.core.
|
|
183
|
+
self.window.core.remote_store.openai.update_status(store.id)
|
|
184
|
+
self.window.core.remote_store.openai.update(store)
|
|
182
185
|
|
|
183
186
|
if update and store.id == self.current:
|
|
184
187
|
self.update_current()
|
|
@@ -207,8 +210,8 @@ class VectorStore:
|
|
|
207
210
|
updated = False
|
|
208
211
|
is_current = False
|
|
209
212
|
for store_id in ids:
|
|
210
|
-
if store_id is not None and store_id in self.window.core.
|
|
211
|
-
store = self.window.core.
|
|
213
|
+
if store_id is not None and store_id in self.window.core.remote_store.openai.items:
|
|
214
|
+
store = self.window.core.remote_store.openai.items[store_id]
|
|
212
215
|
if store is not None:
|
|
213
216
|
self.window.update_status(trans('status.sending'))
|
|
214
217
|
QApplication.processEvents()
|
|
@@ -224,8 +227,8 @@ class VectorStore:
|
|
|
224
227
|
|
|
225
228
|
def update_current(self):
|
|
226
229
|
"""Update current store"""
|
|
227
|
-
if self.current is not None and self.window.core.
|
|
228
|
-
store = self.window.core.
|
|
230
|
+
if self.current is not None and self.window.core.remote_store.openai.has(self.current):
|
|
231
|
+
store = self.window.core.remote_store.openai.items[self.current]
|
|
229
232
|
# update textarea
|
|
230
233
|
option = copy.deepcopy(self.get_option("status"))
|
|
231
234
|
option["value"] = json.dumps(store.status, indent=4)
|
|
@@ -255,7 +258,7 @@ class VectorStore:
|
|
|
255
258
|
:param persist: persist to file and close dialog
|
|
256
259
|
"""
|
|
257
260
|
if self.current is not None:
|
|
258
|
-
current = self.window.core.
|
|
261
|
+
current = self.window.core.remote_store.openai.items[self.current].to_dict()
|
|
259
262
|
options = copy.deepcopy(self.get_options()) # copy options
|
|
260
263
|
data_dict = {}
|
|
261
264
|
for key in options:
|
|
@@ -263,20 +266,20 @@ class VectorStore:
|
|
|
263
266
|
data_dict[key] = current[key] # use initial value
|
|
264
267
|
continue # skip status
|
|
265
268
|
value = self.window.controller.config.get_value(
|
|
266
|
-
parent_id="
|
|
269
|
+
parent_id="remote_store.openai",
|
|
267
270
|
key=key,
|
|
268
271
|
option=options[key],
|
|
269
272
|
)
|
|
270
273
|
data_dict[key] = value
|
|
271
|
-
self.window.core.
|
|
274
|
+
self.window.core.remote_store.openai.items[self.current].from_dict(data_dict)
|
|
272
275
|
|
|
273
276
|
# save config
|
|
274
277
|
if persist:
|
|
275
278
|
self.window.update_status(trans('status.sending'))
|
|
276
279
|
QApplication.processEvents()
|
|
277
280
|
if self.current is not None:
|
|
278
|
-
store = self.window.core.
|
|
279
|
-
self.window.core.
|
|
281
|
+
store = self.window.core.remote_store.openai.update(
|
|
282
|
+
self.window.core.remote_store.openai.items[self.current]
|
|
280
283
|
)
|
|
281
284
|
if store is None:
|
|
282
285
|
self.window.update_status(trans('status.error'))
|
|
@@ -290,8 +293,8 @@ class VectorStore:
|
|
|
290
293
|
|
|
291
294
|
def reload_items(self):
|
|
292
295
|
"""Reload list items"""
|
|
293
|
-
items = self.window.core.
|
|
294
|
-
self.window.
|
|
296
|
+
items = self.window.core.remote_store.openai.items
|
|
297
|
+
self.window.remote_store_openai.update_list("remote_store.openai.list", items)
|
|
295
298
|
self.restore_selection()
|
|
296
299
|
|
|
297
300
|
def restore_selection(self):
|
|
@@ -317,7 +320,7 @@ class VectorStore:
|
|
|
317
320
|
self.window.update_status(trans('status.sending'))
|
|
318
321
|
QApplication.processEvents()
|
|
319
322
|
|
|
320
|
-
store = self.window.core.
|
|
323
|
+
store = self.window.core.remote_store.openai.create()
|
|
321
324
|
if store is None:
|
|
322
325
|
self.window.update_status(trans('status.error'))
|
|
323
326
|
self.window.ui.dialogs.alert("Failed to create new vector store")
|
|
@@ -325,7 +328,7 @@ class VectorStore:
|
|
|
325
328
|
|
|
326
329
|
self.window.update_status(trans('status.assistant.saved'))
|
|
327
330
|
|
|
328
|
-
self.window.core.
|
|
331
|
+
self.window.core.remote_store.openai.update(store)
|
|
329
332
|
self.update() # update stores list in assistant dialog
|
|
330
333
|
|
|
331
334
|
# switch to created store
|
|
@@ -369,9 +372,9 @@ class VectorStore:
|
|
|
369
372
|
"""
|
|
370
373
|
if not force:
|
|
371
374
|
self.window.ui.dialogs.confirm(
|
|
372
|
-
type="
|
|
375
|
+
type="remote_store.openai.delete",
|
|
373
376
|
id=store_id,
|
|
374
|
-
msg=trans("dialog.
|
|
377
|
+
msg=trans("dialog.remote_store.delete.confirm"),
|
|
375
378
|
)
|
|
376
379
|
return
|
|
377
380
|
|
|
@@ -388,10 +391,10 @@ class VectorStore:
|
|
|
388
391
|
self.current = None
|
|
389
392
|
try:
|
|
390
393
|
print("Deleting store: {}".format(store_id))
|
|
391
|
-
if self.window.core.
|
|
394
|
+
if self.window.core.remote_store.openai.delete(store_id):
|
|
392
395
|
self.window.controller.assistant.batch.remove_store_from_assistants(store_id)
|
|
393
396
|
self.window.update_status(trans('status.deleted'))
|
|
394
|
-
self.window.core.
|
|
397
|
+
self.window.core.remote_store.openai.save()
|
|
395
398
|
updated = True
|
|
396
399
|
else:
|
|
397
400
|
self.window.update_status(trans('status.error'))
|
|
@@ -412,15 +415,15 @@ class VectorStore:
|
|
|
412
415
|
:param idx: tab index
|
|
413
416
|
"""
|
|
414
417
|
store_idx = 0
|
|
415
|
-
for id in self.window.core.
|
|
416
|
-
if self.window.core.
|
|
418
|
+
for id in self.window.core.remote_store.openai.get_ids():
|
|
419
|
+
if self.window.core.remote_store.openai.is_hidden(id):
|
|
417
420
|
continue
|
|
418
421
|
if store_idx == idx:
|
|
419
422
|
self.current = id
|
|
420
423
|
break
|
|
421
424
|
store_idx += 1
|
|
422
|
-
current = self.window.ui.models['
|
|
423
|
-
self.window.ui.nodes['
|
|
425
|
+
current = self.window.ui.models['remote_store.openai.list'].index(idx, 0)
|
|
426
|
+
self.window.ui.nodes['remote_store.openai.list'].setCurrentIndex(current)
|
|
424
427
|
|
|
425
428
|
def set_tab_by_id(self, store_id: str):
|
|
426
429
|
"""
|
|
@@ -429,8 +432,8 @@ class VectorStore:
|
|
|
429
432
|
:param store_id: store id
|
|
430
433
|
"""
|
|
431
434
|
idx = self.get_tab_idx(store_id)
|
|
432
|
-
current = self.window.ui.models['
|
|
433
|
-
self.window.ui.nodes['
|
|
435
|
+
current = self.window.ui.models['remote_store.openai.list'].index(idx, 0)
|
|
436
|
+
self.window.ui.nodes['remote_store.openai.list'].setCurrentIndex(current)
|
|
434
437
|
|
|
435
438
|
def get_tab_idx(self, store_id: str) -> int:
|
|
436
439
|
"""
|
|
@@ -441,8 +444,8 @@ class VectorStore:
|
|
|
441
444
|
"""
|
|
442
445
|
store_idx = None
|
|
443
446
|
i = 0
|
|
444
|
-
for id in self.window.core.
|
|
445
|
-
if self.window.core.
|
|
447
|
+
for id in self.window.core.remote_store.openai.get_ids():
|
|
448
|
+
if self.window.core.remote_store.openai.is_hidden(id):
|
|
446
449
|
continue
|
|
447
450
|
if id == store_id:
|
|
448
451
|
store_idx = i
|
|
@@ -459,8 +462,8 @@ class VectorStore:
|
|
|
459
462
|
"""
|
|
460
463
|
idx = None
|
|
461
464
|
i = 0
|
|
462
|
-
for id in self.window.core.
|
|
463
|
-
if self.window.core.
|
|
465
|
+
for id in self.window.core.remote_store.openai.get_ids():
|
|
466
|
+
if self.window.core.remote_store.openai.is_hidden(id):
|
|
464
467
|
continue
|
|
465
468
|
if id == store_id:
|
|
466
469
|
idx = i
|
|
@@ -476,8 +479,8 @@ class VectorStore:
|
|
|
476
479
|
:return: store id / key
|
|
477
480
|
"""
|
|
478
481
|
store_idx = 0
|
|
479
|
-
for id in self.window.core.
|
|
480
|
-
if self.window.core.
|
|
482
|
+
for id in self.window.core.remote_store.openai.get_ids():
|
|
483
|
+
if self.window.core.remote_store.openai.is_hidden(id):
|
|
481
484
|
continue
|
|
482
485
|
if store_idx == idx:
|
|
483
486
|
return id
|
|
@@ -490,8 +493,8 @@ class VectorStore:
|
|
|
490
493
|
|
|
491
494
|
:return: store id
|
|
492
495
|
"""
|
|
493
|
-
for id in self.window.core.
|
|
494
|
-
if not self.window.core.
|
|
496
|
+
for id in self.window.core.remote_store.openai.get_ids():
|
|
497
|
+
if not self.window.core.remote_store.openai.is_hidden(id):
|
|
495
498
|
return id
|
|
496
499
|
return None
|
|
497
500
|
|
|
@@ -501,7 +504,7 @@ class VectorStore:
|
|
|
501
504
|
|
|
502
505
|
:param idx: list index
|
|
503
506
|
"""
|
|
504
|
-
store = self.window.core.
|
|
507
|
+
store = self.window.core.remote_store.openai.get_by_idx(idx)
|
|
505
508
|
if store is None:
|
|
506
509
|
return
|
|
507
510
|
self.current = store
|
|
@@ -519,7 +522,7 @@ class VectorStore:
|
|
|
519
522
|
|
|
520
523
|
:param state: state
|
|
521
524
|
"""
|
|
522
|
-
self.window.core.config.set("
|
|
525
|
+
self.window.core.config.set("remote_store.openai.hide_threads", state)
|
|
523
526
|
self.update()
|
|
524
527
|
|
|
525
528
|
# ==================== Files ====================
|
|
@@ -529,8 +532,8 @@ class VectorStore:
|
|
|
529
532
|
Update files list view for the current store based on local DB.
|
|
530
533
|
This method does not hit the API; it reflects local state.
|
|
531
534
|
"""
|
|
532
|
-
model_id = '
|
|
533
|
-
if '
|
|
535
|
+
model_id = 'remote_store.openai.files.list'
|
|
536
|
+
if 'remote_store.openai.files.list' not in self.window.ui.models:
|
|
534
537
|
return # files panel not initialized yet
|
|
535
538
|
model = self.window.ui.models[model_id]
|
|
536
539
|
try:
|
|
@@ -543,7 +546,7 @@ class VectorStore:
|
|
|
543
546
|
if self.current is None:
|
|
544
547
|
return
|
|
545
548
|
|
|
546
|
-
files_db = self.window.core.
|
|
549
|
+
files_db = self.window.core.remote_store.openai.files
|
|
547
550
|
if files_db is None:
|
|
548
551
|
return
|
|
549
552
|
|
|
@@ -620,13 +623,13 @@ class VectorStore:
|
|
|
620
623
|
|
|
621
624
|
if not force:
|
|
622
625
|
self.window.ui.dialogs.confirm(
|
|
623
|
-
type='
|
|
626
|
+
type='remote_store.openai.file.delete',
|
|
624
627
|
id=idx,
|
|
625
|
-
msg=trans('confirm.
|
|
628
|
+
msg=trans('confirm.remote_store.file.delete'),
|
|
626
629
|
)
|
|
627
630
|
return
|
|
628
631
|
|
|
629
|
-
model_id = '
|
|
632
|
+
model_id = 'remote_store.openai.files.list'
|
|
630
633
|
if model_id not in self.window.ui.models:
|
|
631
634
|
return
|
|
632
635
|
if idx < 0 or idx >= len(self._files_row_to_id):
|
|
@@ -665,7 +668,7 @@ class VectorStore:
|
|
|
665
668
|
|
|
666
669
|
# Remove from local DB
|
|
667
670
|
try:
|
|
668
|
-
self.window.core.
|
|
671
|
+
self.window.core.remote_store.openai.files.delete_by_file_id(file_id)
|
|
669
672
|
except Exception as e:
|
|
670
673
|
self.window.core.debug.log(e)
|
|
671
674
|
|
|
@@ -683,7 +686,7 @@ class VectorStore:
|
|
|
683
686
|
# Trigger re-import for the current store to refresh local DB and UI elsewhere
|
|
684
687
|
try:
|
|
685
688
|
self.window.update_status("Refreshing status...")
|
|
686
|
-
QTimer.singleShot(1000, lambda: self.window.controller.
|
|
689
|
+
QTimer.singleShot(1000, lambda: self.window.controller.remote_store.openai.refresh_status())
|
|
687
690
|
except Exception as e:
|
|
688
691
|
self.window.core.debug.log(e)
|
|
689
692
|
|
|
@@ -0,0 +1,35 @@
|
|
|
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: 2026.01.02 19:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
from .openai import OpenAIRemoteStore
|
|
13
|
+
from .google import GoogleRemoteStore
|
|
14
|
+
|
|
15
|
+
class RemoteStore:
|
|
16
|
+
def __init__(self, window=None):
|
|
17
|
+
"""
|
|
18
|
+
Assistant controller
|
|
19
|
+
|
|
20
|
+
:param window: Window instance
|
|
21
|
+
"""
|
|
22
|
+
self.window = window
|
|
23
|
+
self.openai = OpenAIRemoteStore(window)
|
|
24
|
+
self.google = GoogleRemoteStore(window)
|
|
25
|
+
|
|
26
|
+
def setup(self):
|
|
27
|
+
"""Setup stores"""
|
|
28
|
+
self.window.core.remote_store.openai.load_all()
|
|
29
|
+
self.window.core.remote_store.google.load_all()
|
|
30
|
+
|
|
31
|
+
def reload(self):
|
|
32
|
+
"""Reload stores"""
|
|
33
|
+
self.setup()
|
|
34
|
+
self.window.controller.remote_store.openai.reset()
|
|
35
|
+
self.window.controller.remote_store.google.reset()
|
pygpt_net/controller/ui/ui.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:
|
|
9
|
+
# Updated Date: 2026.01.02 02:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Optional
|
|
@@ -103,6 +103,7 @@ class UI:
|
|
|
103
103
|
self.window.controller.mode.init_list()
|
|
104
104
|
self.window.controller.model.init_list()
|
|
105
105
|
self.init_computer_env()
|
|
106
|
+
self.init_computer_sandbox()
|
|
106
107
|
|
|
107
108
|
def init_computer_env(self):
|
|
108
109
|
"""Init computer environment"""
|
|
@@ -119,6 +120,13 @@ class UI:
|
|
|
119
120
|
if index != -1 and node.currentIndex() != index:
|
|
120
121
|
node.setCurrentIndex(index)
|
|
121
122
|
|
|
123
|
+
def init_computer_sandbox(self):
|
|
124
|
+
"""Init computer sandbox"""
|
|
125
|
+
sandbox = bool(self.window.core.config.get("remote_tools.computer_use.sandbox", False))
|
|
126
|
+
node = self.window.ui.nodes["computer_sandbox"]
|
|
127
|
+
if node.isChecked() != sandbox:
|
|
128
|
+
node.box.setChecked(sandbox)
|
|
129
|
+
|
|
122
130
|
def on_computer_env_changed(self, env: str):
|
|
123
131
|
"""
|
|
124
132
|
Handle computer environment change
|
|
@@ -130,6 +138,17 @@ class UI:
|
|
|
130
138
|
cfg.set("remote_tools.computer_use.env", env)
|
|
131
139
|
cfg.save()
|
|
132
140
|
|
|
141
|
+
def on_computer_sandbox_toggled(self, checked: bool):
|
|
142
|
+
"""
|
|
143
|
+
Handle computer sandbox toggle
|
|
144
|
+
|
|
145
|
+
:param checked: bool
|
|
146
|
+
"""
|
|
147
|
+
cfg = self.window.core.config
|
|
148
|
+
if cfg.get("remote_tools.computer_use.sandbox") != checked:
|
|
149
|
+
cfg.set("remote_tools.computer_use.sandbox", checked)
|
|
150
|
+
cfg.save()
|
|
151
|
+
|
|
133
152
|
def update_toolbox(self):
|
|
134
153
|
"""Update toolbox"""
|
|
135
154
|
ctrl = self.window.controller
|
|
@@ -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:
|
|
9
|
+
# Updated Date: 2026.01.02 20:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Optional, Dict
|
|
@@ -15,9 +15,6 @@ from pygpt_net.item.assistant import AssistantItem
|
|
|
15
15
|
from pygpt_net.item.attachment import AttachmentItem
|
|
16
16
|
from pygpt_net.provider.core.assistant.json_file import JsonFileProvider
|
|
17
17
|
|
|
18
|
-
from .files import Files
|
|
19
|
-
from .store import Store
|
|
20
|
-
|
|
21
18
|
|
|
22
19
|
class Assistants:
|
|
23
20
|
def __init__(self, window=None):
|
|
@@ -27,8 +24,6 @@ class Assistants:
|
|
|
27
24
|
:param window: Window instance
|
|
28
25
|
"""
|
|
29
26
|
self.window = window
|
|
30
|
-
self.files = Files(window)
|
|
31
|
-
self.store = Store(window)
|
|
32
27
|
self.provider = JsonFileProvider(window) # json file provider
|
|
33
28
|
self.current_file = None
|
|
34
29
|
self.items = {}
|
|
@@ -36,8 +31,6 @@ class Assistants:
|
|
|
36
31
|
def install(self):
|
|
37
32
|
"""Install provider data"""
|
|
38
33
|
self.provider.install()
|
|
39
|
-
self.files.install()
|
|
40
|
-
self.store.install()
|
|
41
34
|
|
|
42
35
|
def patch(self, app_version) -> bool:
|
|
43
36
|
"""
|
|
@@ -46,9 +39,7 @@ class Assistants:
|
|
|
46
39
|
:param app_version: app version
|
|
47
40
|
:return: True if data was patched
|
|
48
41
|
"""
|
|
49
|
-
|
|
50
|
-
res2 = self.store.patch(app_version)
|
|
51
|
-
return res1 or res2
|
|
42
|
+
return self.provider.patch(app_version)
|
|
52
43
|
|
|
53
44
|
def get_by_idx(self, idx: int) -> str:
|
|
54
45
|
"""
|
|
@@ -95,8 +86,7 @@ class Assistants:
|
|
|
95
86
|
|
|
96
87
|
:return: assistant ID
|
|
97
88
|
"""
|
|
98
|
-
|
|
99
|
-
return assistant
|
|
89
|
+
return AssistantItem()
|
|
100
90
|
|
|
101
91
|
def add(self, assistant: AssistantItem):
|
|
102
92
|
"""
|
|
@@ -160,8 +150,6 @@ class Assistants:
|
|
|
160
150
|
def load(self):
|
|
161
151
|
"""Load assistants"""
|
|
162
152
|
self.items = self.provider.load()
|
|
163
|
-
self.store.load() # load vector stores
|
|
164
|
-
self.files.load() # load files
|
|
165
153
|
|
|
166
154
|
def save(self):
|
|
167
155
|
"""Save assistants"""
|
pygpt_net/core/db/database.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:
|
|
9
|
+
# Updated Date: 2026.01.02 20:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -173,6 +173,7 @@ class Database:
|
|
|
173
173
|
'file_id',
|
|
174
174
|
'store_id',
|
|
175
175
|
'thread_id',
|
|
176
|
+
'provider',
|
|
176
177
|
'name',
|
|
177
178
|
'path',
|
|
178
179
|
'size',
|
|
@@ -184,6 +185,7 @@ class Database:
|
|
|
184
185
|
'id',
|
|
185
186
|
'store_id',
|
|
186
187
|
'name',
|
|
188
|
+
'provider',
|
|
187
189
|
'usage_bytes',
|
|
188
190
|
'num_files',
|
|
189
191
|
'expire_days',
|
|
@@ -293,7 +295,7 @@ class Database:
|
|
|
293
295
|
'remote_file': {
|
|
294
296
|
'columns': columns["remote_file"],
|
|
295
297
|
'sort_by': columns["remote_file"],
|
|
296
|
-
'search_fields': ['id', 'file_id', 'store_id', 'thread_id', 'name', 'path'],
|
|
298
|
+
'search_fields': ['id', 'file_id', 'store_id', 'thread_id', 'name', 'path', 'provider'],
|
|
297
299
|
'timestamp_columns': ['created_ts', 'updated_ts'],
|
|
298
300
|
'json_columns': [],
|
|
299
301
|
'default_sort': 'id',
|
|
@@ -303,7 +305,7 @@ class Database:
|
|
|
303
305
|
'remote_store': {
|
|
304
306
|
'columns': columns["remote_store"],
|
|
305
307
|
'sort_by': columns["remote_store"],
|
|
306
|
-
'search_fields': ['id', 'store_id', 'uuid', 'name', 'description', 'status', 'status_json'],
|
|
308
|
+
'search_fields': ['id', 'store_id', 'uuid', 'name', 'description', 'status', 'status_json', 'provider'],
|
|
307
309
|
'timestamp_columns': ['created_ts', 'updated_ts', 'last_sync_ts', 'last_active_ts'],
|
|
308
310
|
'json_columns': ['status_json'],
|
|
309
311
|
'default_sort': 'id',
|
pygpt_net/core/filesystem/url.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:
|
|
9
|
+
# Updated Date: 2026.01.03 17:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import QUrl
|
|
@@ -47,6 +47,9 @@ class Url:
|
|
|
47
47
|
elif url.toString().startswith('bridge://play_video/'):
|
|
48
48
|
self.window.controller.media.play_video(url.toString().replace("bridge://play_video/", ""))
|
|
49
49
|
return
|
|
50
|
+
elif url.toString().startswith('bridge://open_image/'):
|
|
51
|
+
self.window.tools.get("viewer").open_preview(url.toString().replace("bridge://open_image/", ""))
|
|
52
|
+
return
|
|
50
53
|
elif url.toString().startswith('bridge://download/'):
|
|
51
54
|
self.window.controller.files.download_local(url.toString().replace("bridge://download/", ""))
|
|
52
55
|
return
|
|
@@ -0,0 +1,35 @@
|
|
|
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: 2026.01.01 15:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
from typing import Optional
|
|
12
|
+
|
|
13
|
+
from pygpt_net.core.types import (
|
|
14
|
+
MODEL_DEFAULT,
|
|
15
|
+
MODEL_DEFAULT_MINI
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def apply(text: Optional[str]) -> str:
|
|
20
|
+
"""
|
|
21
|
+
Apply placeholders to the given text.
|
|
22
|
+
|
|
23
|
+
:param text: input text with placeholders
|
|
24
|
+
:return: text with applied placeholders
|
|
25
|
+
"""
|
|
26
|
+
if text is None:
|
|
27
|
+
return ""
|
|
28
|
+
placeholders = {
|
|
29
|
+
"%MODEL_DEFAULT_MINI%": MODEL_DEFAULT_MINI,
|
|
30
|
+
"%MODEL_DEFAULT%": MODEL_DEFAULT,
|
|
31
|
+
}
|
|
32
|
+
for placeholder, value in placeholders.items():
|
|
33
|
+
if placeholder in text:
|
|
34
|
+
text = text.replace(placeholder, value)
|
|
35
|
+
return text
|
|
@@ -0,0 +1,12 @@
|
|
|
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: 2026.01.02 20:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
from .remote_store import *
|
|
@@ -0,0 +1,11 @@
|
|
|
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: 2026.01.02 20:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
from .store import *
|