pygpt-net 2.6.30__py3-none-any.whl → 2.6.32__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 +7 -1
- pygpt_net/app_core.py +3 -1
- pygpt_net/config.py +3 -1
- pygpt_net/controller/__init__.py +9 -2
- pygpt_net/controller/audio/audio.py +38 -1
- pygpt_net/controller/audio/ui.py +2 -2
- pygpt_net/controller/chat/audio.py +1 -8
- pygpt_net/controller/chat/common.py +23 -62
- pygpt_net/controller/chat/handler/__init__.py +0 -0
- pygpt_net/controller/chat/handler/stream_worker.py +1124 -0
- pygpt_net/controller/chat/output.py +8 -3
- pygpt_net/controller/chat/stream.py +3 -1071
- pygpt_net/controller/chat/text.py +3 -2
- pygpt_net/controller/kernel/kernel.py +11 -3
- pygpt_net/controller/kernel/reply.py +5 -1
- pygpt_net/controller/lang/custom.py +2 -2
- pygpt_net/controller/media/__init__.py +12 -0
- pygpt_net/controller/media/media.py +115 -0
- pygpt_net/controller/realtime/__init__.py +12 -0
- pygpt_net/controller/realtime/manager.py +53 -0
- pygpt_net/controller/realtime/realtime.py +293 -0
- pygpt_net/controller/ui/mode.py +23 -2
- pygpt_net/controller/ui/ui.py +19 -1
- pygpt_net/core/audio/audio.py +6 -1
- pygpt_net/core/audio/backend/native/__init__.py +12 -0
- pygpt_net/core/audio/backend/{native.py → native/native.py} +426 -127
- pygpt_net/core/audio/backend/native/player.py +139 -0
- pygpt_net/core/audio/backend/native/realtime.py +250 -0
- pygpt_net/core/audio/backend/pyaudio/__init__.py +12 -0
- pygpt_net/core/audio/backend/pyaudio/playback.py +194 -0
- pygpt_net/core/audio/backend/pyaudio/pyaudio.py +923 -0
- pygpt_net/core/audio/backend/pyaudio/realtime.py +312 -0
- pygpt_net/core/audio/backend/pygame/__init__.py +12 -0
- pygpt_net/core/audio/backend/{pygame.py → pygame/pygame.py} +130 -19
- pygpt_net/core/audio/backend/shared/__init__.py +38 -0
- pygpt_net/core/audio/backend/shared/conversions.py +211 -0
- pygpt_net/core/audio/backend/shared/envelope.py +38 -0
- pygpt_net/core/audio/backend/shared/player.py +137 -0
- pygpt_net/core/audio/backend/shared/rt.py +52 -0
- pygpt_net/core/audio/capture.py +5 -0
- pygpt_net/core/audio/output.py +14 -2
- pygpt_net/core/audio/whisper.py +6 -2
- pygpt_net/core/bridge/bridge.py +2 -1
- pygpt_net/core/bridge/worker.py +4 -1
- pygpt_net/core/dispatcher/dispatcher.py +37 -1
- pygpt_net/core/events/__init__.py +2 -1
- pygpt_net/core/events/realtime.py +55 -0
- pygpt_net/core/image/image.py +56 -5
- pygpt_net/core/realtime/__init__.py +0 -0
- pygpt_net/core/realtime/options.py +87 -0
- pygpt_net/core/realtime/shared/__init__.py +0 -0
- pygpt_net/core/realtime/shared/audio.py +213 -0
- pygpt_net/core/realtime/shared/loop.py +64 -0
- pygpt_net/core/realtime/shared/session.py +59 -0
- pygpt_net/core/realtime/shared/text.py +37 -0
- pygpt_net/core/realtime/shared/tools.py +276 -0
- pygpt_net/core/realtime/shared/turn.py +38 -0
- pygpt_net/core/realtime/shared/types.py +16 -0
- pygpt_net/core/realtime/worker.py +160 -0
- pygpt_net/core/render/web/body.py +24 -3
- pygpt_net/core/text/utils.py +54 -2
- pygpt_net/core/types/__init__.py +1 -0
- pygpt_net/core/types/image.py +54 -0
- pygpt_net/core/video/__init__.py +12 -0
- pygpt_net/core/video/video.py +290 -0
- pygpt_net/data/config/config.json +26 -5
- pygpt_net/data/config/models.json +221 -103
- pygpt_net/data/config/settings.json +244 -6
- pygpt_net/data/css/web-blocks.css +6 -0
- pygpt_net/data/css/web-chatgpt.css +6 -0
- pygpt_net/data/css/web-chatgpt_wide.css +6 -0
- pygpt_net/data/locale/locale.de.ini +35 -7
- pygpt_net/data/locale/locale.en.ini +56 -17
- pygpt_net/data/locale/locale.es.ini +35 -7
- pygpt_net/data/locale/locale.fr.ini +35 -7
- pygpt_net/data/locale/locale.it.ini +35 -7
- pygpt_net/data/locale/locale.pl.ini +38 -7
- pygpt_net/data/locale/locale.uk.ini +35 -7
- pygpt_net/data/locale/locale.zh.ini +31 -3
- pygpt_net/data/locale/plugin.audio_input.en.ini +4 -0
- pygpt_net/data/locale/plugin.audio_output.en.ini +4 -0
- pygpt_net/data/locale/plugin.cmd_web.en.ini +8 -0
- pygpt_net/item/model.py +22 -1
- pygpt_net/plugin/audio_input/plugin.py +37 -4
- pygpt_net/plugin/audio_input/simple.py +57 -8
- pygpt_net/plugin/cmd_files/worker.py +3 -0
- pygpt_net/provider/api/google/__init__.py +76 -7
- pygpt_net/provider/api/google/audio.py +8 -1
- pygpt_net/provider/api/google/chat.py +45 -6
- pygpt_net/provider/api/google/image.py +226 -86
- pygpt_net/provider/api/google/realtime/__init__.py +12 -0
- pygpt_net/provider/api/google/realtime/client.py +1945 -0
- pygpt_net/provider/api/google/realtime/realtime.py +186 -0
- pygpt_net/provider/api/google/video.py +364 -0
- pygpt_net/provider/api/openai/__init__.py +22 -2
- pygpt_net/provider/api/openai/realtime/__init__.py +12 -0
- pygpt_net/provider/api/openai/realtime/client.py +1828 -0
- pygpt_net/provider/api/openai/realtime/realtime.py +193 -0
- pygpt_net/provider/audio_input/google_genai.py +103 -0
- pygpt_net/provider/audio_output/google_genai_tts.py +229 -0
- pygpt_net/provider/audio_output/google_tts.py +0 -12
- pygpt_net/provider/audio_output/openai_tts.py +8 -5
- pygpt_net/provider/core/config/patch.py +241 -178
- pygpt_net/provider/core/model/patch.py +28 -2
- pygpt_net/provider/llms/google.py +8 -9
- pygpt_net/provider/web/duckduck_search.py +212 -0
- pygpt_net/ui/layout/toolbox/audio.py +55 -0
- pygpt_net/ui/layout/toolbox/footer.py +14 -42
- pygpt_net/ui/layout/toolbox/image.py +7 -13
- pygpt_net/ui/layout/toolbox/raw.py +52 -0
- pygpt_net/ui/layout/toolbox/split.py +48 -0
- pygpt_net/ui/layout/toolbox/toolbox.py +8 -8
- pygpt_net/ui/layout/toolbox/video.py +49 -0
- pygpt_net/ui/widget/option/combo.py +15 -1
- {pygpt_net-2.6.30.dist-info → pygpt_net-2.6.32.dist-info}/METADATA +46 -22
- {pygpt_net-2.6.30.dist-info → pygpt_net-2.6.32.dist-info}/RECORD +121 -73
- pygpt_net/core/audio/backend/pyaudio.py +0 -554
- {pygpt_net-2.6.30.dist-info → pygpt_net-2.6.32.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.30.dist-info → pygpt_net-2.6.32.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.30.dist-info → pygpt_net-2.6.32.dist-info}/entry_points.txt +0 -0
|
@@ -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: 2025.09.01 23:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
from .video import Video
|
|
@@ -0,0 +1,290 @@
|
|
|
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.09.01 23:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
|
|
12
|
+
import uuid
|
|
13
|
+
import os
|
|
14
|
+
import shutil
|
|
15
|
+
import subprocess
|
|
16
|
+
from typing import Optional, List, Dict
|
|
17
|
+
from time import strftime
|
|
18
|
+
|
|
19
|
+
from PySide6.QtCore import Slot, QObject
|
|
20
|
+
|
|
21
|
+
from pygpt_net.core.types import VIDEO_AVAILABLE_ASPECT_RATIOS
|
|
22
|
+
from pygpt_net.item.ctx import CtxItem
|
|
23
|
+
from pygpt_net.utils import trans
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Video(QObject):
|
|
27
|
+
def __init__(self, window=None):
|
|
28
|
+
"""
|
|
29
|
+
Video generation core
|
|
30
|
+
|
|
31
|
+
:param window: Window instance
|
|
32
|
+
"""
|
|
33
|
+
super().__init__()
|
|
34
|
+
self.window = window
|
|
35
|
+
|
|
36
|
+
def install(self):
|
|
37
|
+
"""Install provider data, img dir, etc."""
|
|
38
|
+
img_dir = os.path.join(self.window.core.config.get_user_dir("video"))
|
|
39
|
+
if not os.path.exists(img_dir):
|
|
40
|
+
os.makedirs(img_dir, exist_ok=True)
|
|
41
|
+
|
|
42
|
+
@Slot(object, list, str)
|
|
43
|
+
def handle_finished(
|
|
44
|
+
self,
|
|
45
|
+
ctx: CtxItem,
|
|
46
|
+
paths: List[str],
|
|
47
|
+
prompt: str
|
|
48
|
+
):
|
|
49
|
+
"""
|
|
50
|
+
Handle finished image generation
|
|
51
|
+
|
|
52
|
+
:param ctx: CtxItem
|
|
53
|
+
:param paths: images paths list
|
|
54
|
+
:param prompt: prompt used for generate images
|
|
55
|
+
"""
|
|
56
|
+
self.window.controller.chat.image.handle_response(ctx, paths, prompt)
|
|
57
|
+
|
|
58
|
+
@Slot(object, list, str)
|
|
59
|
+
def handle_finished_inline(
|
|
60
|
+
self,
|
|
61
|
+
ctx: CtxItem,
|
|
62
|
+
paths: List[str],
|
|
63
|
+
prompt: str
|
|
64
|
+
):
|
|
65
|
+
"""
|
|
66
|
+
Handle finished image generation
|
|
67
|
+
|
|
68
|
+
:param ctx: CtxItem
|
|
69
|
+
:param paths: images paths list
|
|
70
|
+
:param prompt: prompt used for generate images
|
|
71
|
+
"""
|
|
72
|
+
self.window.controller.chat.image.handle_response_inline(
|
|
73
|
+
ctx,
|
|
74
|
+
paths,
|
|
75
|
+
prompt,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
@Slot(object)
|
|
79
|
+
def handle_status(self, msg: str):
|
|
80
|
+
"""
|
|
81
|
+
Handle thread status message
|
|
82
|
+
|
|
83
|
+
:param msg: status message
|
|
84
|
+
"""
|
|
85
|
+
self.window.update_status(msg)
|
|
86
|
+
|
|
87
|
+
is_log = False
|
|
88
|
+
if self.window.core.config.has("log.dalle") \
|
|
89
|
+
and self.window.core.config.get("log.dalle"):
|
|
90
|
+
is_log = True
|
|
91
|
+
self.window.core.debug.info(msg, not is_log)
|
|
92
|
+
if is_log:
|
|
93
|
+
print(msg)
|
|
94
|
+
|
|
95
|
+
@Slot(object)
|
|
96
|
+
def handle_error(self, msg: any):
|
|
97
|
+
"""
|
|
98
|
+
Handle thread error message
|
|
99
|
+
|
|
100
|
+
:param msg: error message
|
|
101
|
+
"""
|
|
102
|
+
self.window.update_status(msg)
|
|
103
|
+
self.window.core.debug.log(msg)
|
|
104
|
+
self.window.ui.dialogs.alert(msg)
|
|
105
|
+
|
|
106
|
+
def save_video(self, path: str, video: bytes) -> bool:
|
|
107
|
+
"""
|
|
108
|
+
Save video to file
|
|
109
|
+
|
|
110
|
+
:param path: path to save
|
|
111
|
+
:param video: image data
|
|
112
|
+
:return: True if success
|
|
113
|
+
"""
|
|
114
|
+
try:
|
|
115
|
+
with open(path, 'wb') as file:
|
|
116
|
+
file.write(video)
|
|
117
|
+
try:
|
|
118
|
+
# try to make web compatible
|
|
119
|
+
self.make_web_compatible(path)
|
|
120
|
+
except Exception as e:
|
|
121
|
+
pass
|
|
122
|
+
return True
|
|
123
|
+
except Exception as e:
|
|
124
|
+
print(trans('img.status.save.error') + ": " + str(e))
|
|
125
|
+
return False
|
|
126
|
+
|
|
127
|
+
def make_web_compatible(
|
|
128
|
+
self,
|
|
129
|
+
src_path: str,
|
|
130
|
+
fps: int = 30,
|
|
131
|
+
crf_h264: int = 22,
|
|
132
|
+
crf_vp9: int = 30,
|
|
133
|
+
audio_bitrate: str = "128k",
|
|
134
|
+
make_mp4: bool = True,
|
|
135
|
+
make_webm: bool = True,
|
|
136
|
+
overwrite: bool = True,
|
|
137
|
+
) -> Dict[str, Optional[str]]:
|
|
138
|
+
"""
|
|
139
|
+
Create browser-friendly video variants (MP4 H.264/AAC yuv420p + WebM VP9/Opus yuv420p).
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
dict: {"mp4": "/abs/path/file.web.mp4" or None, "webm": "/abs/path/file.webm" or None}
|
|
143
|
+
|
|
144
|
+
Notes:
|
|
145
|
+
- Requires ffmpeg in PATH.
|
|
146
|
+
- Ensures even dimensions, yuv420p, faststart for MP4, and Opus for WebM.
|
|
147
|
+
- Uses CRF for quality: lower = better (and larger). Tweak crf_h264 / crf_vp9 if needed.
|
|
148
|
+
"""
|
|
149
|
+
if not os.path.isfile(src_path):
|
|
150
|
+
raise FileNotFoundError(f"Source file not found: {src_path}")
|
|
151
|
+
|
|
152
|
+
# Ensure ffmpeg is available
|
|
153
|
+
ffmpeg = shutil.which("ffmpeg")
|
|
154
|
+
if not ffmpeg:
|
|
155
|
+
raise RuntimeError("ffmpeg not found in PATH. Please install ffmpeg.")
|
|
156
|
+
|
|
157
|
+
root, _ = os.path.splitext(os.path.abspath(src_path))
|
|
158
|
+
out_mp4 = f"{root}.web.mp4"
|
|
159
|
+
out_webm = f"{root}.webm"
|
|
160
|
+
|
|
161
|
+
# Remove outputs if overwrite is requested
|
|
162
|
+
if overwrite:
|
|
163
|
+
for p in (out_mp4, out_webm):
|
|
164
|
+
try:
|
|
165
|
+
if os.path.exists(p):
|
|
166
|
+
os.remove(p)
|
|
167
|
+
except Exception:
|
|
168
|
+
pass
|
|
169
|
+
|
|
170
|
+
# Common video filter:
|
|
171
|
+
# - scale to even dimensions (required by many encoders)
|
|
172
|
+
# - format to yuv420p (8-bit), also set SAR=1
|
|
173
|
+
vf = "scale=trunc(iw/2)*2:trunc(ih/2)*2:flags=lanczos,format=yuv420p,setsar=1"
|
|
174
|
+
|
|
175
|
+
results = {"mp4": None, "webm": None}
|
|
176
|
+
|
|
177
|
+
def run_cmd(cmd, dst):
|
|
178
|
+
# Run ffmpeg and return dst on success, None on failure
|
|
179
|
+
try:
|
|
180
|
+
subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
181
|
+
return dst if os.path.exists(dst) else None
|
|
182
|
+
except subprocess.CalledProcessError as e:
|
|
183
|
+
# If needed, print(e.stdout.decode(errors="ignore"))
|
|
184
|
+
return None
|
|
185
|
+
|
|
186
|
+
if make_mp4:
|
|
187
|
+
# H.264 High@4.1, yuv420p, AAC; add faststart for web playback
|
|
188
|
+
mp4_cmd = [
|
|
189
|
+
ffmpeg, "-y",
|
|
190
|
+
"-i", src_path,
|
|
191
|
+
"-map", "0:v:0", "-map", "0:a:0?", # include audio if present
|
|
192
|
+
"-vf", vf,
|
|
193
|
+
"-r", str(fps),
|
|
194
|
+
"-c:v", "libx264",
|
|
195
|
+
"-pix_fmt", "yuv420p",
|
|
196
|
+
"-profile:v", "high", "-level", "4.1",
|
|
197
|
+
"-preset", "medium",
|
|
198
|
+
"-crf", str(crf_h264),
|
|
199
|
+
"-color_primaries", "bt709", "-colorspace", "bt709", "-color_trc", "bt709",
|
|
200
|
+
"-movflags", "+faststart",
|
|
201
|
+
"-c:a", "aac", "-b:a", audio_bitrate, "-ac", "2", "-ar", "48000",
|
|
202
|
+
"-sn",
|
|
203
|
+
out_mp4,
|
|
204
|
+
]
|
|
205
|
+
results["mp4"] = run_cmd(mp4_cmd, out_mp4)
|
|
206
|
+
|
|
207
|
+
if make_webm:
|
|
208
|
+
# VP9 (CRF, constant quality), Opus audio
|
|
209
|
+
webm_cmd = [
|
|
210
|
+
ffmpeg, "-y",
|
|
211
|
+
"-i", src_path,
|
|
212
|
+
"-map", "0:v:0", "-map", "0:a:0?",
|
|
213
|
+
"-vf", vf,
|
|
214
|
+
"-r", str(fps),
|
|
215
|
+
"-c:v", "libvpx-vp9",
|
|
216
|
+
"-b:v", "0", # use CRF mode
|
|
217
|
+
"-crf", str(crf_vp9),
|
|
218
|
+
"-row-mt", "1",
|
|
219
|
+
"-pix_fmt", "yuv420p",
|
|
220
|
+
"-deadline", "good", # "good" for quality; "realtime" for speed
|
|
221
|
+
"-cpu-used", "2", # lower = slower/better; tweak for performance
|
|
222
|
+
"-c:a", "libopus", "-b:a", audio_bitrate, "-ac", "2", "-ar", "48000",
|
|
223
|
+
"-sn",
|
|
224
|
+
out_webm,
|
|
225
|
+
]
|
|
226
|
+
results["webm"] = run_cmd(webm_cmd, out_webm)
|
|
227
|
+
|
|
228
|
+
return results
|
|
229
|
+
|
|
230
|
+
def make_safe_filename(self, name: str) -> str:
|
|
231
|
+
"""
|
|
232
|
+
Make safe filename
|
|
233
|
+
|
|
234
|
+
:param name: filename to make safe
|
|
235
|
+
:return: safe filename
|
|
236
|
+
"""
|
|
237
|
+
def safe_char(c):
|
|
238
|
+
if c.isalnum():
|
|
239
|
+
return c
|
|
240
|
+
else:
|
|
241
|
+
return "_"
|
|
242
|
+
return "".join(safe_char(c) for c in name).rstrip("_")[:30]
|
|
243
|
+
|
|
244
|
+
def gen_unique_path(self, ctx: CtxItem):
|
|
245
|
+
"""
|
|
246
|
+
Generate unique image path based on context
|
|
247
|
+
|
|
248
|
+
:param ctx: CtxItem
|
|
249
|
+
:return: unique image path
|
|
250
|
+
"""
|
|
251
|
+
img_id = uuid.uuid4()
|
|
252
|
+
dt_prefix = strftime("%Y%m%d_%H%M%S")
|
|
253
|
+
img_dir = self.window.core.config.get_user_dir("img")
|
|
254
|
+
filename = f"{dt_prefix}_{img_id}.png"
|
|
255
|
+
return os.path.join(img_dir, filename)
|
|
256
|
+
|
|
257
|
+
def _normalize_model_name(self, model: str) -> str:
|
|
258
|
+
"""
|
|
259
|
+
Normalize model id (strip optional 'models/' prefix).
|
|
260
|
+
|
|
261
|
+
:param model: model id
|
|
262
|
+
"""
|
|
263
|
+
try:
|
|
264
|
+
return model.split("/")[-1]
|
|
265
|
+
except Exception:
|
|
266
|
+
return model
|
|
267
|
+
|
|
268
|
+
def get_aspect_ratio_option(self) -> dict:
|
|
269
|
+
"""
|
|
270
|
+
Get image resolution option for UI
|
|
271
|
+
|
|
272
|
+
:return: dict
|
|
273
|
+
"""
|
|
274
|
+
return {
|
|
275
|
+
"type": "combo",
|
|
276
|
+
"slider": True,
|
|
277
|
+
"label": "video.aspect_ratio",
|
|
278
|
+
"value": "16:9",
|
|
279
|
+
"keys": self.get_available_aspect_ratio(),
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
def get_available_aspect_ratio(self, model: str = None) -> Dict[str, str]:
|
|
283
|
+
"""
|
|
284
|
+
Get available image resolutions
|
|
285
|
+
|
|
286
|
+
:param model: model name
|
|
287
|
+
:return: dict of available resolutions
|
|
288
|
+
"""
|
|
289
|
+
return VIDEO_AVAILABLE_ASPECT_RATIOS
|
|
290
|
+
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"__meta__": {
|
|
3
|
-
"version": "2.6.
|
|
4
|
-
"app.version": "2.6.
|
|
5
|
-
"updated_at": "2025-
|
|
3
|
+
"version": "2.6.32",
|
|
4
|
+
"app.version": "2.6.32",
|
|
5
|
+
"updated_at": "2025-09-02T00:00:00"
|
|
6
6
|
},
|
|
7
7
|
"access.audio.event.speech": false,
|
|
8
8
|
"access.audio.event.speech.disabled": [],
|
|
@@ -89,6 +89,11 @@
|
|
|
89
89
|
"api_key_voyage": "",
|
|
90
90
|
"api_key_open_router": "",
|
|
91
91
|
"api_native_google": true,
|
|
92
|
+
"api_native_google.use_vertex": false,
|
|
93
|
+
"api_native_google.cloud_project": "",
|
|
94
|
+
"api_native_google.cloud_location": "us-central1",
|
|
95
|
+
"api_native_google.app_credentials": "",
|
|
96
|
+
"api_key_open_router": "",
|
|
92
97
|
"api_proxy": "",
|
|
93
98
|
"api_use_responses": true,
|
|
94
99
|
"api_use_responses_llama": false,
|
|
@@ -106,6 +111,8 @@
|
|
|
106
111
|
"attachments_capture_clear": true,
|
|
107
112
|
"audio.cache.enabled": true,
|
|
108
113
|
"audio.cache.max_files": 1000,
|
|
114
|
+
"audio.input.auto_turn": false,
|
|
115
|
+
"audio.input.loop": false,
|
|
109
116
|
"audio.input.backend": "native",
|
|
110
117
|
"audio.input.channels": 1,
|
|
111
118
|
"audio.input.continuous": false,
|
|
@@ -114,6 +121,8 @@
|
|
|
114
121
|
"audio.input.stop_interval": 10,
|
|
115
122
|
"audio.input.timeout": 120,
|
|
116
123
|
"audio.input.timeout.continuous": false,
|
|
124
|
+
"audio.input.vad.prefix": 300,
|
|
125
|
+
"audio.input.vad.silence": 2000,
|
|
117
126
|
"audio.output.backend": "native",
|
|
118
127
|
"audio.output.device": "0",
|
|
119
128
|
"audio.transcribe.convert_video": true,
|
|
@@ -196,7 +205,7 @@
|
|
|
196
205
|
"frequency_penalty": 0.0,
|
|
197
206
|
"img_prompt_model": "gpt-4o",
|
|
198
207
|
"img_raw": true,
|
|
199
|
-
"img_resolution": "
|
|
208
|
+
"img_resolution": "1024x1024",
|
|
200
209
|
"img_quality": "standard",
|
|
201
210
|
"img_variants": 1,
|
|
202
211
|
"interpreter.auto_clear": false,
|
|
@@ -330,6 +339,7 @@
|
|
|
330
339
|
"log.level": "error",
|
|
331
340
|
"log.llama": false,
|
|
332
341
|
"log.plugins": false,
|
|
342
|
+
"log.realtime": false,
|
|
333
343
|
"max_output_tokens": 0,
|
|
334
344
|
"max_requests_limit": 60,
|
|
335
345
|
"max_tokens_length": 32000,
|
|
@@ -383,7 +393,9 @@
|
|
|
383
393
|
"prompt.ctx.auto_summary.user": "Summarize topic of this conversation in one sentence. Use best keywords to describe it. Summary must be in the same language as the conversation and it will be used for conversation title so it must be EXTREMELY SHORT and concise - use maximum 5 words: \n\nHuman: {input}\nAI Assistant: {output}",
|
|
384
394
|
"prompt.default": "You are a helpful assistant.",
|
|
385
395
|
"prompt.expert": "# EXPERT MODE IS ENABLED:\n\nYou are a very helpful asssistant and the professional manager of a team of experts, each of whom is the best in their respective fields.\n\n## Rules:\n\n- Instead of directly answering questions, you will manage these experts by forwarding queries to them, collecting their responses, controlling the flow of information between them, and sending requests to them.\n- Experts are distinct, specialized AI models running on my local machine.\n- You will serve as a bridge between them.\n- Each expert has their own conversation context, allowing you to communicate with them normally.\n- The experts can communicate with you but not with each other, making you responsible for relaying information between them.\n- Each expert can use tools and commands, for example, reading files or searching the Web. You can ask experts to call tools and commands.\n- After consulting with the experts, your task is to prepare the best possible answer based on the assistance received.\n- To send a request to an expert, prepare the \"expert_call\" tool. Remember to format the JSON tool as shown, surrounding the tool with `<tool></tool>` tags, for example: `<tool>{\"cmd\": \"expert_call\", \"params\": {\"id\": \"expert_id\", \"query\": \"some query\"}}</tool>`. Make sure the JSON object is syntactically correct, without any redundand parenthness.\n- DO NOT call any remote tools when calling the experts.\n- Remember that the call must contain a query and the ID of the expert to whom the query is being forwarded.\n- Use ONLY the experts listed below; DO NOT TRY to ask any non-existent experts\u2014they will not respond.\n- Do not respond to the expert's replies or use the JSON tool again if replying; the expert only has the ability to listen to your queries sent via the JSON command and to respond to them.\n- Always follow ALL user commands, even if you think the expert can't do something. Experts are allowed to execute commands just as you can.\n- After querying an expert, always wait for the expert's response before sending another query.\n- Do not try to query experts in the middle of the conversation; put your queries and commands at the end of the text.\n- Always call only one expert at a time.\n- Always execute only one command at a time.\n- Always use the language used by the user in the conversation.\n- Never write as a called expert and do not imagine a response from them; instead, always wait for the response from the expert.\n- Every message sent to you directly after your query is always a response from the asked expert, not from me.\n- Always send a direct, clear, and detailed prompt to the expert, without any \"Please...\", \"Could you...\", etc.\n- Always forward all the messages that the user wants to send to the expert, without any exceptions.\n-- If a user command appears outside an expert's scope, fulfill the request regardless, without refusal.\n\n## List of allowed experts, along with their IDs:\n\n{presets}",
|
|
386
|
-
"prompt.img": "Convert
|
|
396
|
+
"prompt.img": "Convert the user's request into a single, production\u2011ready description for generating one high\u2011quality still image. Output only the description text, nothing else.\n\nWrite in concise, vivid, present\u2011tense language. Do not use commands (no \u201cplease generate\u201d), model names, parameters, or metadata. Do not mention aspect ratio, resolution, steps, seed, or negative prompts. Avoid on\u2011image text, captions, watermarks, logos, and UI elements. No brands, celebrities, or living artists unless explicitly provided by the user.\n\nInclude, woven into a coherent paragraph:\n- Clear primary subject(s) and their pose, action, and expression.\n- Setting and environment with time of day, season, weather, and atmosphere.\n- Composition and camera viewpoint (e.g., close\u2011up portrait, wide establishing, eye\u2011level, low\u2011angle, top\u2011down), framing (rule of thirds, centered symmetry), and background/foreground separation.\n- Lens and focus behavior (e.g., 85\u202fmm portrait, macro, shallow depth of field, smooth bokeh, gentle focus falloff).\n- Lighting style and quality (e.g., soft diffused daylight, golden hour rim light, dramatic chiaroscuro, studio three\u2011point) and how it shapes forms and shadows.\n- Color palette and grading (e.g., warm cinematic teal\u2011and\u2011orange, muted earth tones, cool monochrome with a single accent color).\n- Visual style or medium (e.g., photorealistic photography, watercolor illustration, oil painting, pencil sketch, anime cel\u2011shading, 3D render, isometric).\n- Material and surface detail (e.g., skin texture, fabric weave, wood grain, metal patina) to enhance realism or stylization.\n- Spatial depth cues (foreground/midground/background layering, atmospheric perspective) and overall mood.\n\nIf the user specifies a genre, era, or style, preserve it and enrich it with consistent, concrete traits. If the request is vague, infer specific but reasonable details that enhance clarity without contradicting the user\u2019s intent.\n\nReturn only the final visual description.",
|
|
397
|
+
"prompt.video": "Convert the user's request into a single, production-ready description for generating one continuous video clip. Output only the description text, nothing else.\n\nWrite in concise, vivid, present-tense language. Do not use commands (no \u201cplease generate\u201d), model names, parameters, or metadata. Do not mention duration, aspect ratio, FPS, resolution, shot numbers, cuts, or lists. Focus on visuals only; no dialogue, captions, on\u2011screen text, watermarks, logos, or UI.\n\nInclude, in a coherent way:\n- Clear subject(s) and what they are doing.\n- Setting, time of day, atmosphere, and weather.\n- Camera perspective and motion (e.g., wide establishing, low\u2011angle tracking, slow dolly in, aerial, handheld), framing and composition.\n- Lens and focus behavior (e.g., 24\u202fmm wide, shallow depth of field, gentle rack focus).\n- Lighting style and quality (e.g., soft golden hour rim light, moody volumetric shafts).\n- Color palette and grading (e.g., warm cinematic teal\u2011and\u2011orange, desaturated documentary).\n- Visual style or medium (e.g., photoreal live\u2011action, stylized anime, stop\u2011motion clay, watercolor animation).\n- Material and surface details that reinforce realism or the chosen style.\n- Temporal progression within one shot (use cues like \u201cas\u2026\u201d, \u201cthen\u2026\u201d, \u201cwhile\u2026\u201d), maintaining physical plausibility and continuity.\n\nIf the user specifies a genre or style (e.g., cyberpunk, nature documentary), keep it and expand with consistent, concrete visual traits. If the request is vague, infer specific but reasonable details that enhance clarity without contradicting the user\u2019s intent.\n\nReturn only the final visual description.",
|
|
398
|
+
"realtime.auto_turn": true,
|
|
387
399
|
"render.blocks": true,
|
|
388
400
|
"render.engine": "web",
|
|
389
401
|
"render.open_gl": false,
|
|
@@ -399,6 +411,7 @@
|
|
|
399
411
|
"remote_tools.computer_use.env": "",
|
|
400
412
|
"remote_tools.google.web_search": true,
|
|
401
413
|
"remote_tools.google.code_interpreter": false,
|
|
414
|
+
"remote_tools.google.url_ctx": false,
|
|
402
415
|
"send_clear": true,
|
|
403
416
|
"send_mode": 2,
|
|
404
417
|
"store_history": true,
|
|
@@ -491,6 +504,14 @@
|
|
|
491
504
|
"video.player.path": "",
|
|
492
505
|
"video.player.volume": 100,
|
|
493
506
|
"video.player.volume.mute": false,
|
|
507
|
+
"video.aspect_ratio": "16:9",
|
|
508
|
+
"video.duration": 8,
|
|
509
|
+
"video.fps": 24,
|
|
510
|
+
"video.seed": "",
|
|
511
|
+
"video.negative_prompt": "",
|
|
512
|
+
"video.generate_audio": false,
|
|
513
|
+
"video.prompt_model": "gemini-2.5-flash",
|
|
514
|
+
"video.resolution": "720p",
|
|
494
515
|
"vision.capture.auto": false,
|
|
495
516
|
"vision.capture.enabled": false,
|
|
496
517
|
"vision.capture.height": 720,
|