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.01 15:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from pygpt_net.core.types import MODEL_DEFAULT_MINI
|
|
@@ -65,7 +65,7 @@ class Config(BaseConfig):
|
|
|
65
65
|
use="models",
|
|
66
66
|
value=MODEL_DEFAULT_MINI,
|
|
67
67
|
label="Model for question preparation",
|
|
68
|
-
description="Model used to prepare question before asking Llama-index, default: gpt-
|
|
68
|
+
description="Model used to prepare question before asking Llama-index, default: gpt-4o-mini",
|
|
69
69
|
tooltip="Model",
|
|
70
70
|
)
|
|
71
71
|
plugin.add_option(
|
pygpt_net/preload.py
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
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: 2025.12.31 17:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
# -------------------------------------------------- #
|
|
13
|
+
# Lightweight splash window (separate process)
|
|
14
|
+
# -------------------------------------------------- #
|
|
15
|
+
def _splash_main(conn, title="PyGPT", message="Loading…"):
|
|
16
|
+
"""
|
|
17
|
+
Minimal splash process using PySide6. Runs its own event loop and
|
|
18
|
+
listens for commands on a Pipe: {"type": "msg", "text": "..."} or {"type": "quit"}.
|
|
19
|
+
"""
|
|
20
|
+
try:
|
|
21
|
+
# Import locally to keep the main process import path untouched
|
|
22
|
+
from PySide6 import QtCore, QtWidgets
|
|
23
|
+
except Exception:
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
# Enable HiDPI (safe defaults)
|
|
28
|
+
try:
|
|
29
|
+
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling, True)
|
|
30
|
+
QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
|
|
31
|
+
except Exception:
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
app = QtWidgets.QApplication(["pygpt_splash"])
|
|
35
|
+
|
|
36
|
+
# Root window styled as splash
|
|
37
|
+
root = QtWidgets.QWidget(
|
|
38
|
+
None,
|
|
39
|
+
QtCore.Qt.SplashScreen
|
|
40
|
+
| QtCore.Qt.FramelessWindowHint
|
|
41
|
+
| QtCore.Qt.WindowStaysOnTopHint
|
|
42
|
+
)
|
|
43
|
+
root.setAttribute(QtCore.Qt.WA_TranslucentBackground, True)
|
|
44
|
+
root.setObjectName("SplashRoot")
|
|
45
|
+
|
|
46
|
+
panel = QtWidgets.QFrame(root)
|
|
47
|
+
panel.setObjectName("SplashPanel")
|
|
48
|
+
panel.setStyleSheet("""
|
|
49
|
+
#SplashPanel {
|
|
50
|
+
background-color: rgba(30, 30, 30, 230);
|
|
51
|
+
border-radius: 12px;
|
|
52
|
+
}
|
|
53
|
+
QLabel { color: #ffffff; }
|
|
54
|
+
""")
|
|
55
|
+
layout = QtWidgets.QVBoxLayout(panel)
|
|
56
|
+
layout.setContentsMargins(16, 16, 16, 16)
|
|
57
|
+
layout.setSpacing(8)
|
|
58
|
+
|
|
59
|
+
lbl_title = QtWidgets.QLabel(title, panel)
|
|
60
|
+
lbl_title.setAlignment(QtCore.Qt.AlignCenter)
|
|
61
|
+
lbl_title.setStyleSheet("font-size: 16px; font-weight: 600;")
|
|
62
|
+
|
|
63
|
+
lbl_wait = QtWidgets.QLabel("Initializing...")
|
|
64
|
+
lbl_wait.setAlignment(QtCore.Qt.AlignCenter)
|
|
65
|
+
lbl_wait.setStyleSheet("font-size: 12px;")
|
|
66
|
+
|
|
67
|
+
lbl_msg = QtWidgets.QLabel(message, panel)
|
|
68
|
+
lbl_msg.setAlignment(QtCore.Qt.AlignCenter)
|
|
69
|
+
lbl_msg.setStyleSheet("font-size: 12px;")
|
|
70
|
+
|
|
71
|
+
bar = QtWidgets.QProgressBar(panel)
|
|
72
|
+
bar.setRange(0, 0)
|
|
73
|
+
bar.setTextVisible(False)
|
|
74
|
+
bar.setFixedHeight(8)
|
|
75
|
+
bar.setStyleSheet("QProgressBar { border: 0px; border-radius: 4px; } "
|
|
76
|
+
"QProgressBar::chunk { background-color: #3f3f3f; }")
|
|
77
|
+
|
|
78
|
+
layout.addWidget(lbl_title)
|
|
79
|
+
layout.addWidget(lbl_msg)
|
|
80
|
+
layout.addWidget(bar)
|
|
81
|
+
layout.addWidget(lbl_wait)
|
|
82
|
+
|
|
83
|
+
panel.setFixedSize(360, 120)
|
|
84
|
+
panel.move(0, 0)
|
|
85
|
+
root.resize(panel.size())
|
|
86
|
+
|
|
87
|
+
# Center on primary screen
|
|
88
|
+
screen = app.primaryScreen()
|
|
89
|
+
if screen:
|
|
90
|
+
geo = screen.availableGeometry()
|
|
91
|
+
root.move(geo.center() - root.rect().center())
|
|
92
|
+
|
|
93
|
+
# Ensure initial transparency for fade-in
|
|
94
|
+
try:
|
|
95
|
+
root.setWindowOpacity(0.0)
|
|
96
|
+
except Exception:
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
root.show()
|
|
100
|
+
|
|
101
|
+
# Fade-in on start (non-blocking, resilient to platform limitations)
|
|
102
|
+
try:
|
|
103
|
+
def _start_fade_in():
|
|
104
|
+
try:
|
|
105
|
+
anim = QtCore.QPropertyAnimation(root, b"windowOpacity")
|
|
106
|
+
anim.setDuration(300)
|
|
107
|
+
anim.setStartValue(0.0)
|
|
108
|
+
anim.setEndValue(1.0)
|
|
109
|
+
root._fade_in_anim = anim # keep reference to avoid GC
|
|
110
|
+
anim.start()
|
|
111
|
+
except Exception:
|
|
112
|
+
try:
|
|
113
|
+
root.setWindowOpacity(1.0)
|
|
114
|
+
except Exception:
|
|
115
|
+
pass
|
|
116
|
+
|
|
117
|
+
QtCore.QTimer.singleShot(0, _start_fade_in)
|
|
118
|
+
except Exception:
|
|
119
|
+
try:
|
|
120
|
+
root.setWindowOpacity(1.0)
|
|
121
|
+
except Exception:
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
# Poll the pipe for messages and close requests
|
|
125
|
+
timer = QtCore.QTimer()
|
|
126
|
+
timer.setInterval(80)
|
|
127
|
+
|
|
128
|
+
def poll():
|
|
129
|
+
try:
|
|
130
|
+
if conn.poll():
|
|
131
|
+
msg = conn.recv()
|
|
132
|
+
if isinstance(msg, dict):
|
|
133
|
+
t = msg.get("type")
|
|
134
|
+
if t == "quit":
|
|
135
|
+
# Stop fade-in if it is running to avoid conflicting animations
|
|
136
|
+
try:
|
|
137
|
+
if hasattr(root, "_fade_in_anim") and root._fade_in_anim is not None:
|
|
138
|
+
root._fade_in_anim.stop()
|
|
139
|
+
except Exception:
|
|
140
|
+
pass
|
|
141
|
+
# Fade-out and quit
|
|
142
|
+
try:
|
|
143
|
+
anim = QtCore.QPropertyAnimation(root, b"windowOpacity")
|
|
144
|
+
anim.setDuration(180)
|
|
145
|
+
anim.setStartValue(root.windowOpacity())
|
|
146
|
+
anim.setEndValue(0.0)
|
|
147
|
+
anim.finished.connect(app.quit)
|
|
148
|
+
# Keep reference to avoid GC
|
|
149
|
+
root._fade_anim = anim
|
|
150
|
+
anim.start()
|
|
151
|
+
except Exception:
|
|
152
|
+
app.quit()
|
|
153
|
+
elif t == "msg":
|
|
154
|
+
text = msg.get("text", "")
|
|
155
|
+
if text:
|
|
156
|
+
lbl_msg.setText(text)
|
|
157
|
+
elif isinstance(msg, str):
|
|
158
|
+
if msg.lower() == "quit":
|
|
159
|
+
app.quit()
|
|
160
|
+
except (EOFError, OSError):
|
|
161
|
+
# Parent died or pipe closed: exit
|
|
162
|
+
app.quit()
|
|
163
|
+
|
|
164
|
+
timer.timeout.connect(poll)
|
|
165
|
+
timer.start()
|
|
166
|
+
|
|
167
|
+
# Failsafe timeout (can be overridden via env)
|
|
168
|
+
import os as _os
|
|
169
|
+
timeout_ms = int(_os.environ.get("PYGPT_SPLASH_TIMEOUT", "120000"))
|
|
170
|
+
killer = QtCore.QTimer()
|
|
171
|
+
killer.setSingleShot(True)
|
|
172
|
+
killer.timeout.connect(app.quit)
|
|
173
|
+
killer.start(timeout_ms)
|
|
174
|
+
|
|
175
|
+
app.exec()
|
|
176
|
+
except Exception:
|
|
177
|
+
# No crash propagation to main app
|
|
178
|
+
pass
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class _Preloader:
|
|
182
|
+
"""
|
|
183
|
+
Controller for the splash subprocess.
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
def __init__(self, proc, conn):
|
|
187
|
+
self._proc = proc
|
|
188
|
+
self._conn = conn
|
|
189
|
+
|
|
190
|
+
def set_message(self, text):
|
|
191
|
+
try:
|
|
192
|
+
if self._conn:
|
|
193
|
+
self._conn.send({"type": "msg", "text": str(text)})
|
|
194
|
+
except Exception:
|
|
195
|
+
pass
|
|
196
|
+
|
|
197
|
+
def close(self, wait=True, timeout=2.0):
|
|
198
|
+
try:
|
|
199
|
+
if self._conn:
|
|
200
|
+
try:
|
|
201
|
+
self._conn.send({"type": "quit"})
|
|
202
|
+
except Exception:
|
|
203
|
+
pass
|
|
204
|
+
finally:
|
|
205
|
+
if wait and self._proc is not None:
|
|
206
|
+
self._proc.join(timeout=timeout)
|
|
207
|
+
if self._proc is not None and self._proc.is_alive():
|
|
208
|
+
try:
|
|
209
|
+
self._proc.terminate()
|
|
210
|
+
except Exception:
|
|
211
|
+
pass
|
|
212
|
+
self._conn = None
|
|
213
|
+
self._proc = None
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _start_preloader(title="PyGPT", message="Loading…"):
|
|
217
|
+
"""
|
|
218
|
+
Start splash as a separate process using 'spawn' on every OS.
|
|
219
|
+
Returns a _Preloader controller or None if failed.
|
|
220
|
+
"""
|
|
221
|
+
try:
|
|
222
|
+
import multiprocessing as mp
|
|
223
|
+
try:
|
|
224
|
+
ctx = mp.get_context("spawn")
|
|
225
|
+
except ValueError:
|
|
226
|
+
ctx = mp
|
|
227
|
+
|
|
228
|
+
parent_conn, child_conn = ctx.Pipe(duplex=True)
|
|
229
|
+
proc = ctx.Process(
|
|
230
|
+
target=_splash_main,
|
|
231
|
+
args=(child_conn, title, message),
|
|
232
|
+
daemon=True
|
|
233
|
+
)
|
|
234
|
+
proc.start()
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
child_conn.close()
|
|
238
|
+
except Exception:
|
|
239
|
+
pass
|
|
240
|
+
|
|
241
|
+
return _Preloader(proc, parent_conn)
|
|
242
|
+
except Exception:
|
|
243
|
+
return None
|
|
@@ -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
|
|
@@ -22,16 +22,20 @@ from pygpt_net.core.types import (
|
|
|
22
22
|
MODE_COMPLETION,
|
|
23
23
|
MODE_IMAGE,
|
|
24
24
|
MODE_RESEARCH,
|
|
25
|
+
MODE_COMPUTER,
|
|
25
26
|
)
|
|
26
27
|
from pygpt_net.core.bridge.context import BridgeContext
|
|
27
28
|
from pygpt_net.item.model import ModelItem
|
|
28
29
|
|
|
29
30
|
from .chat import Chat
|
|
31
|
+
from .computer import Computer
|
|
30
32
|
from .vision import Vision
|
|
31
33
|
from .tools import Tools
|
|
32
34
|
from .audio import Audio
|
|
33
35
|
from .image import Image
|
|
34
36
|
from .realtime import Realtime
|
|
37
|
+
from .remote_tools import RemoteTools
|
|
38
|
+
from .store import Store
|
|
35
39
|
from .video import Video
|
|
36
40
|
from .music import Music
|
|
37
41
|
|
|
@@ -51,6 +55,9 @@ class ApiGoogle:
|
|
|
51
55
|
self.realtime = Realtime(window)
|
|
52
56
|
self.video = Video(window)
|
|
53
57
|
self.music = Music(window)
|
|
58
|
+
self.computer = Computer(window)
|
|
59
|
+
self.remote_tools = RemoteTools(window)
|
|
60
|
+
self.store = Store(window)
|
|
54
61
|
self.client: Optional[genai.Client] = None
|
|
55
62
|
self.locked = False
|
|
56
63
|
self.last_client_args: Optional[Dict[str, Any]] = None
|
|
@@ -125,7 +132,13 @@ class ApiGoogle:
|
|
|
125
132
|
used_tokens = 0
|
|
126
133
|
response = None
|
|
127
134
|
|
|
128
|
-
if mode in [
|
|
135
|
+
if mode in [
|
|
136
|
+
MODE_COMPLETION,
|
|
137
|
+
MODE_CHAT,
|
|
138
|
+
MODE_AUDIO,
|
|
139
|
+
MODE_RESEARCH,
|
|
140
|
+
MODE_COMPUTER
|
|
141
|
+
]:
|
|
129
142
|
|
|
130
143
|
# Live API for audio streaming
|
|
131
144
|
if mode == MODE_AUDIO and stream:
|
|
@@ -226,7 +239,7 @@ class ApiGoogle:
|
|
|
226
239
|
"""
|
|
227
240
|
# with remote tools
|
|
228
241
|
base_tools = self.tools.prepare(model, functions)
|
|
229
|
-
remote_tools = self.build_remote_tools(model)
|
|
242
|
+
remote_tools = self.remote_tools.build_remote_tools(model)
|
|
230
243
|
tools = (base_tools or []) + (remote_tools or [])
|
|
231
244
|
"""
|
|
232
245
|
|
|
@@ -262,57 +275,6 @@ class ApiGoogle:
|
|
|
262
275
|
finally:
|
|
263
276
|
self.locked = False
|
|
264
277
|
|
|
265
|
-
def build_remote_tools(self, model: ModelItem = None) -> list:
|
|
266
|
-
"""
|
|
267
|
-
Build Google GenAI remote tools based on config flags.
|
|
268
|
-
- remote_tools.google.web_search: enables grounding via Google Search (Gemini 2.x)
|
|
269
|
-
or GoogleSearchRetrieval (Gemini 1.5 fallback).
|
|
270
|
-
- remote_tools.google.code_interpreter: enables code execution tool.
|
|
271
|
-
|
|
272
|
-
Returns a list of gtypes.Tool objects (can be empty).
|
|
273
|
-
|
|
274
|
-
:param model: ModelItem
|
|
275
|
-
:return: list of gtypes.Tool
|
|
276
|
-
"""
|
|
277
|
-
tools: list = []
|
|
278
|
-
cfg = self.window.core.config
|
|
279
|
-
model_id = (model.id if model and getattr(model, "id", None) else "").lower()
|
|
280
|
-
is_web = self.window.controller.chat.remote_tools.enabled(model, "web_search") # get global config
|
|
281
|
-
|
|
282
|
-
# Google Search tool
|
|
283
|
-
if is_web and "image" not in model.id:
|
|
284
|
-
try:
|
|
285
|
-
if not model_id.startswith("gemini-1.5") and not model_id.startswith("models/gemini-1.5"):
|
|
286
|
-
# Gemini 2.x uses GoogleSearch
|
|
287
|
-
tools.append(gtypes.Tool(google_search=gtypes.GoogleSearch()))
|
|
288
|
-
else:
|
|
289
|
-
# Gemini 1.5 fallback uses GoogleSearchRetrieval
|
|
290
|
-
# Note: Supported only for 1.5 models.
|
|
291
|
-
tools.append(gtypes.Tool(
|
|
292
|
-
google_search_retrieval=gtypes.GoogleSearchRetrieval()
|
|
293
|
-
))
|
|
294
|
-
except Exception as e:
|
|
295
|
-
# Do not break the request if tool construction fails
|
|
296
|
-
self.window.core.debug.log(e)
|
|
297
|
-
|
|
298
|
-
# Code Execution tool
|
|
299
|
-
if cfg.get("remote_tools.google.code_interpreter") and "image" not in model.id:
|
|
300
|
-
try:
|
|
301
|
-
tools.append(gtypes.Tool(code_execution=gtypes.ToolCodeExecution))
|
|
302
|
-
except Exception as e:
|
|
303
|
-
self.window.core.debug.log(e)
|
|
304
|
-
|
|
305
|
-
# URL Context tool
|
|
306
|
-
if cfg.get("remote_tools.google.url_ctx") and "image" not in model.id:
|
|
307
|
-
try:
|
|
308
|
-
# Supported on Gemini 2.x+ models (not on 1.5)
|
|
309
|
-
if not model_id.startswith("gemini-1.5") and not model_id.startswith("models/gemini-1.5"):
|
|
310
|
-
tools.append(gtypes.Tool(url_context=gtypes.UrlContext))
|
|
311
|
-
except Exception as e:
|
|
312
|
-
self.window.core.debug.log(e)
|
|
313
|
-
|
|
314
|
-
return tools
|
|
315
|
-
|
|
316
278
|
def setup_env(self) -> bool:
|
|
317
279
|
"""
|
|
318
280
|
Setup environment variables for VertexAI via Google GenAI API
|