pygpt-net 2.7.3__py3-none-any.whl → 2.7.5__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 +3 -3
- pygpt_net/app.py +382 -350
- 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/attachment.py +5 -1
- pygpt_net/controller/chat/handler/google_stream.py +307 -1
- pygpt_net/controller/chat/handler/worker.py +8 -1
- pygpt_net/controller/chat/image.py +15 -3
- pygpt_net/controller/dialogs/confirm.py +73 -101
- pygpt_net/controller/files/files.py +3 -1
- pygpt_net/controller/lang/mapping.py +9 -9
- pygpt_net/controller/layout/layout.py +2 -2
- 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/theme/nodes.py +2 -1
- pygpt_net/controller/ui/mode.py +5 -1
- pygpt_net/controller/ui/ui.py +36 -2
- 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/helpers.py +5 -0
- pygpt_net/data/config/config.json +8 -5
- pygpt_net/data/config/models.json +77 -3
- pygpt_net/data/config/settings.json +45 -14
- pygpt_net/data/css/web-blocks.css +3 -0
- pygpt_net/data/css/web-chatgpt.css +3 -0
- pygpt_net/data/locale/locale.de.ini +43 -41
- pygpt_net/data/locale/locale.en.ini +56 -44
- pygpt_net/data/locale/locale.es.ini +43 -41
- pygpt_net/data/locale/locale.fr.ini +43 -41
- pygpt_net/data/locale/locale.it.ini +43 -41
- pygpt_net/data/locale/locale.pl.ini +43 -41
- pygpt_net/data/locale/locale.uk.ini +43 -41
- pygpt_net/data/locale/locale.zh.ini +43 -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 -1
- pygpt_net/item/store.py +238 -0
- pygpt_net/launcher.py +115 -55
- pygpt_net/migrations/Version20260102190000.py +35 -0
- pygpt_net/migrations/__init__.py +3 -1
- pygpt_net/plugin/cmd_mouse_control/config.py +470 -1
- pygpt_net/plugin/cmd_mouse_control/plugin.py +488 -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/preload.py +243 -0
- pygpt_net/provider/api/google/__init__.py +16 -54
- pygpt_net/provider/api/google/chat.py +546 -129
- pygpt_net/provider/api/google/computer.py +190 -0
- pygpt_net/provider/api/google/image.py +74 -6
- 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/video.py +9 -4
- 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/computer.py +10 -1
- pygpt_net/provider/api/openai/image.py +42 -19
- pygpt_net/provider/api/openai/store.py +6 -6
- pygpt_net/provider/api/openai/video.py +27 -2
- pygpt_net/provider/api/openai/worker/importer.py +24 -24
- pygpt_net/provider/api/x_ai/image.py +25 -2
- pygpt_net/provider/core/config/patch.py +23 -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/ui/base/config_dialog.py +3 -2
- 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/chat/input.py +20 -2
- pygpt_net/ui/layout/chat/painter.py +6 -4
- pygpt_net/ui/layout/toolbox/computer_env.py +26 -8
- pygpt_net/ui/layout/toolbox/image.py +5 -5
- pygpt_net/ui/layout/toolbox/video.py +5 -4
- pygpt_net/ui/main.py +84 -3
- pygpt_net/ui/menu/tools.py +13 -5
- pygpt_net/ui/widget/dialog/base.py +3 -10
- 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/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 +158 -4
- pygpt_net/ui/widget/textarea/input_extra.py +664 -0
- {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.dist-info}/METADATA +48 -9
- {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.dist-info}/RECORD +157 -130
- {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.dist-info}/LICENSE +0 -0
- {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.dist-info}/WHEEL +0 -0
- {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.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 os
|
|
@@ -36,17 +36,17 @@ class Importer(QObject):
|
|
|
36
36
|
if mode == "assistants":
|
|
37
37
|
self.window.controller.assistant.batch.handle_imported_assistants_failed(err)
|
|
38
38
|
elif mode == "import_files":
|
|
39
|
-
self.window.controller.
|
|
39
|
+
self.window.controller.remote_store.openai.batch.handle_imported_files_failed(err)
|
|
40
40
|
elif mode == "truncate_files":
|
|
41
|
-
self.window.controller.
|
|
41
|
+
self.window.controller.remote_store.openai.batch.handle_truncated_files_failed(err)
|
|
42
42
|
elif mode == "upload_files":
|
|
43
|
-
self.window.controller.
|
|
43
|
+
self.window.controller.remote_store.openai.batch.handle_uploaded_files_failed(err)
|
|
44
44
|
elif mode in "vector_stores":
|
|
45
|
-
self.window.controller.
|
|
45
|
+
self.window.controller.remote_store.openai.batch.handle_imported_stores_failed(err)
|
|
46
46
|
elif mode in "truncate_vector_stores":
|
|
47
|
-
self.window.controller.
|
|
47
|
+
self.window.controller.remote_store.openai.batch.handle_truncated_stores_failed(err)
|
|
48
48
|
elif mode in "refresh_vector_stores":
|
|
49
|
-
self.window.controller.
|
|
49
|
+
self.window.controller.remote_store.openai.batch.handle_refreshed_stores_failed(err)
|
|
50
50
|
|
|
51
51
|
@Slot(str, str, int)
|
|
52
52
|
def handle_finished(self, mode: str, store_id: str = None, num: int = 0):
|
|
@@ -60,17 +60,17 @@ class Importer(QObject):
|
|
|
60
60
|
if mode == "assistants":
|
|
61
61
|
self.window.controller.assistant.batch.handle_imported_assistants(num)
|
|
62
62
|
elif mode == "import_files":
|
|
63
|
-
self.window.controller.
|
|
63
|
+
self.window.controller.remote_store.openai.batch.handle_imported_files(num)
|
|
64
64
|
elif mode == "truncate_files":
|
|
65
|
-
self.window.controller.
|
|
65
|
+
self.window.controller.remote_store.openai.batch.handle_truncated_files(store_id, num)
|
|
66
66
|
elif mode == "upload_files":
|
|
67
|
-
self.window.controller.
|
|
67
|
+
self.window.controller.remote_store.openai.batch.handle_uploaded_files(num)
|
|
68
68
|
elif mode == "vector_stores":
|
|
69
|
-
self.window.controller.
|
|
69
|
+
self.window.controller.remote_store.openai.batch.handle_imported_stores(num)
|
|
70
70
|
elif mode == "truncate_vector_stores":
|
|
71
|
-
self.window.controller.
|
|
71
|
+
self.window.controller.remote_store.openai.batch.handle_truncated_stores(num)
|
|
72
72
|
elif mode == "refresh_vector_stores":
|
|
73
|
-
self.window.controller.
|
|
73
|
+
self.window.controller.remote_store.openai.batch.handle_refreshed_stores(num)
|
|
74
74
|
|
|
75
75
|
@Slot(str, str)
|
|
76
76
|
def handle_status(self, mode: str, msg: str):
|
|
@@ -264,10 +264,10 @@ class ImportWorker(QRunnable):
|
|
|
264
264
|
"""
|
|
265
265
|
try:
|
|
266
266
|
self.log("Importing vector stores...")
|
|
267
|
-
self.window.core.
|
|
267
|
+
self.window.core.remote_store.openai.clear()
|
|
268
268
|
items = {}
|
|
269
269
|
self.window.core.api.openai.store.import_stores(items, callback=self.callback)
|
|
270
|
-
self.window.core.
|
|
270
|
+
self.window.core.remote_store.openai.import_items(items)
|
|
271
271
|
if not silent:
|
|
272
272
|
self.signals.finished.emit("vector_stores", self.store_id, len(items))
|
|
273
273
|
return True
|
|
@@ -286,8 +286,8 @@ class ImportWorker(QRunnable):
|
|
|
286
286
|
try:
|
|
287
287
|
self.log("Truncating stores...")
|
|
288
288
|
num = self.window.core.api.openai.store.remove_all(callback=self.callback)
|
|
289
|
-
self.window.core.
|
|
290
|
-
self.window.core.
|
|
289
|
+
self.window.core.remote_store.openai.items = {}
|
|
290
|
+
self.window.core.remote_store.openai.save()
|
|
291
291
|
if not silent:
|
|
292
292
|
self.signals.finished.emit("truncate_vector_stores", self.store_id, num)
|
|
293
293
|
return True
|
|
@@ -306,11 +306,11 @@ class ImportWorker(QRunnable):
|
|
|
306
306
|
try:
|
|
307
307
|
self.log("Refreshing stores...")
|
|
308
308
|
num = 0
|
|
309
|
-
stores = self.window.core.
|
|
309
|
+
stores = self.window.core.remote_store.openai.items
|
|
310
310
|
for id in stores:
|
|
311
311
|
store = stores[id]
|
|
312
312
|
try:
|
|
313
|
-
self.window.controller.
|
|
313
|
+
self.window.controller.remote_store.openai.refresh_store(store, update=False)
|
|
314
314
|
num += 1
|
|
315
315
|
except Exception as e:
|
|
316
316
|
self.log("Failed to refresh store: {}".format(id))
|
|
@@ -334,12 +334,12 @@ class ImportWorker(QRunnable):
|
|
|
334
334
|
# if empty store_id, truncate all files, otherwise truncate only store files
|
|
335
335
|
if self.store_id is None:
|
|
336
336
|
self.log("Truncating all files...")
|
|
337
|
-
self.window.core.
|
|
337
|
+
self.window.core.remote_store.openai.files.truncate() # clear all files
|
|
338
338
|
# remove all files in API
|
|
339
339
|
num = self.window.core.api.openai.store.remove_files(callback=self.callback)
|
|
340
340
|
else:
|
|
341
341
|
self.log("Truncating files for store: {}".format(self.store_id))
|
|
342
|
-
self.window.core.
|
|
342
|
+
self.window.core.remote_store.openai.files.truncate(self.store_id) # clear store files, remove from stores / DB
|
|
343
343
|
# remove store files in API
|
|
344
344
|
num = self.window.core.api.openai.store.remove_store_files(
|
|
345
345
|
self.store_id,
|
|
@@ -373,7 +373,7 @@ class ImportWorker(QRunnable):
|
|
|
373
373
|
)
|
|
374
374
|
if stored_file is not None:
|
|
375
375
|
data = self.window.core.api.openai.store.get_file(file_id)
|
|
376
|
-
self.window.core.
|
|
376
|
+
self.window.core.remote_store.openai.files.insert(self.store_id, data) # insert to DB
|
|
377
377
|
msg = "Uploaded file: {}/{}".format((num + 1), len(self.files))
|
|
378
378
|
self.signals.status.emit("upload_files", msg)
|
|
379
379
|
self.log(msg)
|
|
@@ -402,11 +402,11 @@ class ImportWorker(QRunnable):
|
|
|
402
402
|
try:
|
|
403
403
|
if self.store_id is None:
|
|
404
404
|
self.log("Importing all files...")
|
|
405
|
-
self.window.core.
|
|
405
|
+
self.window.core.remote_store.openai.files.truncate_local() # clear local DB (all)
|
|
406
406
|
num = self.window.core.api.openai.store.import_stores_files(self.callback) # import all files
|
|
407
407
|
else:
|
|
408
408
|
self.log("Importing files for store: {}".format(self.store_id))
|
|
409
|
-
self.window.core.
|
|
409
|
+
self.window.core.remote_store.openai.files.truncate_local(self.store_id) # clear local DB (all)
|
|
410
410
|
items = self.window.core.api.openai.store.import_store_files(
|
|
411
411
|
self.store_id,
|
|
412
412
|
[],
|
|
@@ -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: 2025.
|
|
9
|
+
# Updated Date: 2025.12.31 16:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import base64
|
|
@@ -49,6 +49,7 @@ class Image:
|
|
|
49
49
|
prompt = context.prompt
|
|
50
50
|
num = int(extra.get("num", 1))
|
|
51
51
|
inline = bool(extra.get("inline", False))
|
|
52
|
+
extra_prompt = extra.get("extra_prompt", "")
|
|
52
53
|
|
|
53
54
|
# Optional prompt enhancement model (same as in your Google path)
|
|
54
55
|
prompt_model = self.window.core.models.from_defaults()
|
|
@@ -66,6 +67,7 @@ class Image:
|
|
|
66
67
|
worker.raw = self.window.core.config.get('img_raw')
|
|
67
68
|
worker.num = num
|
|
68
69
|
worker.inline = inline
|
|
70
|
+
worker.extra_prompt = extra_prompt
|
|
69
71
|
|
|
70
72
|
self.worker = worker
|
|
71
73
|
self.worker.signals.finished.connect(self.window.core.image.handle_finished)
|
|
@@ -102,6 +104,7 @@ class ImageWorker(QRunnable):
|
|
|
102
104
|
self.input_prompt = ""
|
|
103
105
|
self.system_prompt = ""
|
|
104
106
|
self.inline = False
|
|
107
|
+
self.extra_prompt: Optional[str] = None
|
|
105
108
|
self.raw = False
|
|
106
109
|
self.num = 1
|
|
107
110
|
|
|
@@ -131,6 +134,13 @@ class ImageWorker(QRunnable):
|
|
|
131
134
|
self.signals.error.emit(e)
|
|
132
135
|
self.signals.status.emit(trans('img.status.prompt.error') + ": " + str(e))
|
|
133
136
|
|
|
137
|
+
# Negative prompt fallback: append as textual instruction (xAI has no native field for it)
|
|
138
|
+
if self.extra_prompt and str(self.extra_prompt).strip():
|
|
139
|
+
try:
|
|
140
|
+
self.input_prompt = self._merge_negative_prompt(self.input_prompt or "", self.extra_prompt)
|
|
141
|
+
except Exception:
|
|
142
|
+
pass
|
|
143
|
+
|
|
134
144
|
self.signals.status.emit(trans('img.status.generating') + f": {self.input_prompt}...")
|
|
135
145
|
|
|
136
146
|
cfg = self.window.core.config
|
|
@@ -205,4 +215,17 @@ class ImageWorker(QRunnable):
|
|
|
205
215
|
try:
|
|
206
216
|
sig.deleteLater()
|
|
207
217
|
except RuntimeError:
|
|
208
|
-
pass
|
|
218
|
+
pass
|
|
219
|
+
|
|
220
|
+
# ---------- prompt utilities ----------
|
|
221
|
+
|
|
222
|
+
@staticmethod
|
|
223
|
+
def _merge_negative_prompt(prompt: str, negative: Optional[str]) -> str:
|
|
224
|
+
"""
|
|
225
|
+
Append a negative prompt to the main text prompt for providers without a native negative_prompt field.
|
|
226
|
+
"""
|
|
227
|
+
base = (prompt or "").strip()
|
|
228
|
+
neg = (negative or "").strip()
|
|
229
|
+
if not neg:
|
|
230
|
+
return base
|
|
231
|
+
return (base + ("\n" if base else "") + f"Negative prompt: {neg}").strip()
|
|
@@ -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
|
import copy
|
|
@@ -216,6 +216,28 @@ class Patch:
|
|
|
216
216
|
data["img.remix"] = False
|
|
217
217
|
updated = True
|
|
218
218
|
|
|
219
|
+
# < 2.7.4
|
|
220
|
+
if old < parse_version("2.7.4"):
|
|
221
|
+
print("Migrating config from < 2.7.4...")
|
|
222
|
+
patch_css('web-chatgpt.css', True)
|
|
223
|
+
patch_css('web-blocks.css', True)
|
|
224
|
+
updated = True
|
|
225
|
+
|
|
226
|
+
# < 2.7.5
|
|
227
|
+
if old < parse_version("2.7.5"):
|
|
228
|
+
print("Migrating config from < 2.7.5...")
|
|
229
|
+
if "remote_tools.computer_use.sandbox" not in data:
|
|
230
|
+
data["remote_tools.computer_use.sandbox"] = False
|
|
231
|
+
if "remote_tools.google.file_search" not in data:
|
|
232
|
+
data["remote_tools.google.file_search"] = False
|
|
233
|
+
if "remote_tools.google.file_search.args" not in data:
|
|
234
|
+
data["remote_tools.google.file_search.args"] = ""
|
|
235
|
+
if "remote_tools.google.maps" not in data:
|
|
236
|
+
data["remote_tools.google.maps"] = False
|
|
237
|
+
if "remote_store.openai.hide_threads" not in data:
|
|
238
|
+
data["remote_store.openai.hide_threads"] = True
|
|
239
|
+
updated = True
|
|
240
|
+
|
|
219
241
|
# update file
|
|
220
242
|
migrated = False
|
|
221
243
|
if updated:
|
|
@@ -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 copy
|
|
@@ -1404,8 +1404,8 @@ class Patch:
|
|
|
1404
1404
|
# < 2.1.79
|
|
1405
1405
|
if old < parse_version("2.1.79"):
|
|
1406
1406
|
print("Migrating config from < 2.1.79...")
|
|
1407
|
-
if '
|
|
1408
|
-
data["
|
|
1407
|
+
if 'remote_store.openai.hide_threads' not in data:
|
|
1408
|
+
data["remote_store.openai.hide_threads"] = True
|
|
1409
1409
|
updated = True
|
|
1410
1410
|
|
|
1411
1411
|
# < 2.2.2
|
|
@@ -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 02:10:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from packaging.version import parse as parse_version, Version
|
|
@@ -75,7 +75,7 @@ class Patch:
|
|
|
75
75
|
base_model = from_base(model)
|
|
76
76
|
if base_model:
|
|
77
77
|
data[model] = base_model
|
|
78
|
-
|
|
78
|
+
updated = True
|
|
79
79
|
|
|
80
80
|
# < 2.6.67 <--- add missing image input
|
|
81
81
|
if old < parse_version("2.6.67"):
|
|
@@ -100,7 +100,21 @@ class Patch:
|
|
|
100
100
|
m = data[model]
|
|
101
101
|
if not m.is_image_input():
|
|
102
102
|
m.input.append("image")
|
|
103
|
-
|
|
103
|
+
updated = True
|
|
104
|
+
|
|
105
|
+
# < 2.7.5 <--- add: gemini-2.5-computer-use-preview-10-2025
|
|
106
|
+
if old < parse_version("2.7.5"):
|
|
107
|
+
print("Migrating models from < 2.7.5...")
|
|
108
|
+
models_to_add = [
|
|
109
|
+
"gemini-2.5-computer-use-preview-10-2025",
|
|
110
|
+
"deep-research-pro-preview-12-2025"
|
|
111
|
+
]
|
|
112
|
+
for model in models_to_add:
|
|
113
|
+
if model not in data:
|
|
114
|
+
base_model = from_base(model)
|
|
115
|
+
if base_model:
|
|
116
|
+
data[model] = base_model
|
|
117
|
+
updated = True
|
|
104
118
|
|
|
105
119
|
# update file
|
|
106
120
|
if updated:
|
|
@@ -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 json
|
|
@@ -77,9 +77,12 @@ class JsonFileProvider(BaseProvider):
|
|
|
77
77
|
if filename.endswith(".json"):
|
|
78
78
|
path = os.path.join(self.window.core.config.get_user_dir('presets'), filename)
|
|
79
79
|
with open(path, 'r', encoding="utf-8") as f:
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
try:
|
|
81
|
+
preset = PresetItem()
|
|
82
|
+
self.deserialize(json.load(f), preset)
|
|
83
|
+
items[filename[:-5]] = preset
|
|
84
|
+
except Exception as e:
|
|
85
|
+
pass
|
|
83
86
|
except Exception as e:
|
|
84
87
|
self.window.core.debug.log(e)
|
|
85
88
|
|
|
@@ -104,9 +107,12 @@ class JsonFileProvider(BaseProvider):
|
|
|
104
107
|
filename
|
|
105
108
|
)
|
|
106
109
|
with open(path, 'r', encoding="utf-8") as f:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
+
try:
|
|
111
|
+
preset = PresetItem()
|
|
112
|
+
self.deserialize(json.load(f), preset)
|
|
113
|
+
items[filename[:-5]] = preset
|
|
114
|
+
except Exception as e:
|
|
115
|
+
pass
|
|
110
116
|
except Exception as e:
|
|
111
117
|
self.window.core.debug.log(e)
|
|
112
118
|
|
|
@@ -6,20 +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:
|
|
9
|
+
# Updated Date: 2026.01.02 20:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Dict
|
|
13
13
|
from packaging.version import Version
|
|
14
14
|
|
|
15
|
-
from pygpt_net.item.
|
|
15
|
+
from pygpt_net.item.store import RemoteFileItem
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class BaseProvider:
|
|
19
19
|
def __init__(self, window=None):
|
|
20
20
|
self.window = window
|
|
21
21
|
self.id = ""
|
|
22
|
-
self.type = "
|
|
22
|
+
self.type = "remote_file"
|
|
23
23
|
|
|
24
24
|
def attach(self, window):
|
|
25
25
|
self.window = window
|
|
@@ -30,25 +30,25 @@ class BaseProvider:
|
|
|
30
30
|
def patch(self, version: Version) -> bool:
|
|
31
31
|
pass
|
|
32
32
|
|
|
33
|
-
def create(self, file:
|
|
33
|
+
def create(self, file: RemoteFileItem):
|
|
34
34
|
pass
|
|
35
35
|
|
|
36
|
-
def load(self, id) ->
|
|
36
|
+
def load(self, id) -> RemoteFileItem:
|
|
37
37
|
pass
|
|
38
38
|
|
|
39
|
-
def load_all(self) -> Dict[str,
|
|
39
|
+
def load_all(self, provider: str) -> Dict[str, RemoteFileItem]:
|
|
40
40
|
pass
|
|
41
41
|
|
|
42
|
-
def save(self, file:
|
|
42
|
+
def save(self, file: RemoteFileItem):
|
|
43
43
|
pass
|
|
44
44
|
|
|
45
|
-
def save_all(self, items: Dict[str,
|
|
45
|
+
def save_all(self, items: Dict[str, RemoteFileItem]):
|
|
46
46
|
pass
|
|
47
47
|
|
|
48
48
|
def remove(self, id):
|
|
49
49
|
pass
|
|
50
50
|
|
|
51
|
-
def truncate(self):
|
|
51
|
+
def truncate(self, provider: str):
|
|
52
52
|
pass
|
|
53
53
|
|
|
54
54
|
def get_version(self) -> str:
|
|
@@ -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 .provider import *
|
|
@@ -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 packaging.version import parse as parse_version, Version
|
|
@@ -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 uuid
|
|
@@ -14,8 +14,8 @@ from typing import Dict
|
|
|
14
14
|
|
|
15
15
|
from packaging.version import Version
|
|
16
16
|
|
|
17
|
-
from pygpt_net.item.
|
|
18
|
-
from pygpt_net.provider.core.
|
|
17
|
+
from pygpt_net.item.store import RemoteFileItem
|
|
18
|
+
from pygpt_net.provider.core.remote_file.base import BaseProvider
|
|
19
19
|
|
|
20
20
|
from .patch import Patch
|
|
21
21
|
from .storage import Storage
|
|
@@ -28,7 +28,7 @@ class DbSqliteProvider(BaseProvider):
|
|
|
28
28
|
self.patcher = Patch(window, self)
|
|
29
29
|
self.storage = Storage(window)
|
|
30
30
|
self.id = "db_sqlite"
|
|
31
|
-
self.type = "
|
|
31
|
+
self.type = "remote_file"
|
|
32
32
|
|
|
33
33
|
def attach(self, window):
|
|
34
34
|
"""
|
|
@@ -56,11 +56,11 @@ class DbSqliteProvider(BaseProvider):
|
|
|
56
56
|
"""
|
|
57
57
|
return str(uuid.uuid4())
|
|
58
58
|
|
|
59
|
-
def create(self, file:
|
|
59
|
+
def create(self, file: RemoteFileItem) -> int:
|
|
60
60
|
"""
|
|
61
61
|
Create new and return its ID
|
|
62
62
|
|
|
63
|
-
:param file:
|
|
63
|
+
:param file: RemoteFileItem
|
|
64
64
|
:return: file ID
|
|
65
65
|
"""
|
|
66
66
|
if file.record_id is None or file.record_id == "":
|
|
@@ -68,15 +68,16 @@ class DbSqliteProvider(BaseProvider):
|
|
|
68
68
|
file.record_id = self.storage.insert(file)
|
|
69
69
|
return file.record_id
|
|
70
70
|
|
|
71
|
-
def load_all(self) -> Dict[str,
|
|
71
|
+
def load_all(self, provider: str) -> Dict[str, RemoteFileItem]:
|
|
72
72
|
"""
|
|
73
73
|
Load files from DB
|
|
74
74
|
|
|
75
|
+
:param provider: provider ID
|
|
75
76
|
:return: files dict
|
|
76
77
|
"""
|
|
77
|
-
return self.storage.get_all()
|
|
78
|
+
return self.storage.get_all(provider)
|
|
78
79
|
|
|
79
|
-
def load(self, id: int) ->
|
|
80
|
+
def load(self, id: int) -> RemoteFileItem:
|
|
80
81
|
"""
|
|
81
82
|
Load file from DB
|
|
82
83
|
|
|
@@ -85,11 +86,11 @@ class DbSqliteProvider(BaseProvider):
|
|
|
85
86
|
"""
|
|
86
87
|
return self.storage.get_by_id(id)
|
|
87
88
|
|
|
88
|
-
def save(self, file:
|
|
89
|
+
def save(self, file: RemoteFileItem):
|
|
89
90
|
"""
|
|
90
91
|
Save file to DB
|
|
91
92
|
|
|
92
|
-
:param file:
|
|
93
|
+
:param file: RemoteFileItem
|
|
93
94
|
"""
|
|
94
95
|
try:
|
|
95
96
|
self.storage.save(file)
|
|
@@ -97,11 +98,11 @@ class DbSqliteProvider(BaseProvider):
|
|
|
97
98
|
self.window.core.debug.log(e)
|
|
98
99
|
print("Error while saving filed: {}".format(str(e)))
|
|
99
100
|
|
|
100
|
-
def save_all(self, items: Dict[str,
|
|
101
|
+
def save_all(self, items: Dict[str, RemoteFileItem]):
|
|
101
102
|
"""
|
|
102
103
|
Save all files to DB
|
|
103
104
|
|
|
104
|
-
:param items: dict of
|
|
105
|
+
:param items: dict of RemoteFileItem objects
|
|
105
106
|
"""
|
|
106
107
|
try:
|
|
107
108
|
for id in items:
|
|
@@ -113,15 +114,15 @@ class DbSqliteProvider(BaseProvider):
|
|
|
113
114
|
|
|
114
115
|
def get_by_store_or_thread(self, store_id: str, thread_id: str) -> dict:
|
|
115
116
|
"""
|
|
116
|
-
Return dict with
|
|
117
|
+
Return dict with RemoteFileItem objects, indexed by record ID
|
|
117
118
|
|
|
118
|
-
:return: dict of
|
|
119
|
+
:return: dict of RemoteFileItem objects
|
|
119
120
|
"""
|
|
120
121
|
return self.storage.get_by_store_or_thread(store_id, thread_id)
|
|
121
122
|
|
|
122
123
|
def count_by_store_or_thread(self, store_id: str, thread_id: str) -> int:
|
|
123
124
|
"""
|
|
124
|
-
Count
|
|
125
|
+
Count RemoteFileItem objects, indexed by ID
|
|
125
126
|
|
|
126
127
|
:return: number of files
|
|
127
128
|
"""
|
|
@@ -163,13 +164,14 @@ class DbSqliteProvider(BaseProvider):
|
|
|
163
164
|
"""
|
|
164
165
|
return self.storage.clear_store_from_files(store_id)
|
|
165
166
|
|
|
166
|
-
def clear_all_stores_from_files(self) -> bool:
|
|
167
|
+
def clear_all_stores_from_files(self, provider: str) -> bool:
|
|
167
168
|
"""
|
|
168
169
|
Clear all stores from files
|
|
169
170
|
|
|
171
|
+
:param provider: provider ID
|
|
170
172
|
:return: True if deleted
|
|
171
173
|
"""
|
|
172
|
-
return self.storage.clear_all_stores_from_files()
|
|
174
|
+
return self.storage.clear_all_stores_from_files(provider)
|
|
173
175
|
|
|
174
176
|
def rename_file(self, record_id: int, name: str) -> bool:
|
|
175
177
|
"""
|
|
@@ -181,13 +183,14 @@ class DbSqliteProvider(BaseProvider):
|
|
|
181
183
|
"""
|
|
182
184
|
return self.storage.rename_file(record_id, name)
|
|
183
185
|
|
|
184
|
-
def truncate_all(self) -> bool:
|
|
186
|
+
def truncate_all(self, provider: str) -> bool:
|
|
185
187
|
"""
|
|
186
188
|
Truncate all files
|
|
187
189
|
|
|
190
|
+
:param provider: provider ID
|
|
188
191
|
:return: True if truncated
|
|
189
192
|
"""
|
|
190
|
-
return self.storage.truncate_all()
|
|
193
|
+
return self.storage.truncate_all(provider)
|
|
191
194
|
|
|
192
195
|
def truncate_by_store(self, store_id: str) -> bool:
|
|
193
196
|
"""
|