pygpt-net 2.6.29__py3-none-any.whl → 2.6.31__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 +4 -0
- pygpt_net/{container.py → app_core.py} +5 -6
- pygpt_net/controller/__init__.py +5 -2
- pygpt_net/controller/access/control.py +1 -9
- pygpt_net/controller/assistant/assistant.py +4 -4
- pygpt_net/controller/assistant/batch.py +7 -7
- pygpt_net/controller/assistant/files.py +4 -4
- pygpt_net/controller/assistant/threads.py +3 -3
- pygpt_net/controller/attachment/attachment.py +4 -7
- pygpt_net/controller/audio/audio.py +25 -1
- pygpt_net/controller/audio/ui.py +2 -2
- pygpt_net/controller/chat/audio.py +1 -8
- pygpt_net/controller/chat/common.py +30 -4
- pygpt_net/controller/chat/handler/stream_worker.py +1124 -0
- pygpt_net/controller/chat/output.py +8 -3
- pygpt_net/controller/chat/stream.py +4 -405
- pygpt_net/controller/chat/text.py +3 -2
- pygpt_net/controller/chat/vision.py +11 -19
- pygpt_net/controller/config/placeholder.py +1 -1
- pygpt_net/controller/ctx/ctx.py +1 -1
- pygpt_net/controller/ctx/summarizer.py +1 -1
- pygpt_net/controller/kernel/kernel.py +11 -3
- pygpt_net/controller/kernel/reply.py +5 -1
- pygpt_net/controller/mode/mode.py +21 -12
- pygpt_net/controller/plugins/settings.py +3 -2
- pygpt_net/controller/presets/editor.py +112 -99
- pygpt_net/controller/realtime/__init__.py +12 -0
- pygpt_net/controller/realtime/manager.py +53 -0
- pygpt_net/controller/realtime/realtime.py +268 -0
- pygpt_net/controller/theme/theme.py +3 -2
- pygpt_net/controller/ui/mode.py +7 -0
- pygpt_net/controller/ui/ui.py +19 -1
- pygpt_net/controller/ui/vision.py +4 -4
- pygpt_net/core/agents/legacy.py +2 -2
- pygpt_net/core/agents/runners/openai_workflow.py +2 -2
- pygpt_net/core/assistants/files.py +5 -5
- pygpt_net/core/assistants/store.py +4 -4
- 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 +275 -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 +13 -2
- pygpt_net/core/audio/whisper.py +6 -2
- pygpt_net/core/bridge/bridge.py +4 -3
- pygpt_net/core/bridge/worker.py +31 -9
- pygpt_net/core/debug/console/console.py +2 -2
- pygpt_net/core/debug/presets.py +2 -2
- 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/experts/experts.py +2 -2
- pygpt_net/core/image/image.py +51 -1
- pygpt_net/core/modes/modes.py +2 -2
- pygpt_net/core/presets/presets.py +3 -3
- 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 +164 -0
- pygpt_net/core/tokens/tokens.py +4 -4
- pygpt_net/core/types/__init__.py +1 -0
- pygpt_net/core/types/image.py +48 -0
- pygpt_net/core/types/mode.py +5 -2
- pygpt_net/core/vision/analyzer.py +1 -1
- pygpt_net/data/config/config.json +13 -4
- pygpt_net/data/config/models.json +219 -101
- pygpt_net/data/config/modes.json +3 -9
- pygpt_net/data/config/settings.json +135 -27
- pygpt_net/data/config/settings_section.json +2 -2
- pygpt_net/data/locale/locale.de.ini +7 -7
- pygpt_net/data/locale/locale.en.ini +25 -12
- pygpt_net/data/locale/locale.es.ini +7 -7
- pygpt_net/data/locale/locale.fr.ini +7 -7
- pygpt_net/data/locale/locale.it.ini +7 -7
- pygpt_net/data/locale/locale.pl.ini +8 -8
- pygpt_net/data/locale/locale.uk.ini +7 -7
- pygpt_net/data/locale/locale.zh.ini +3 -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/item/model.py +23 -3
- 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/plugin/openai_dalle/plugin.py +4 -4
- pygpt_net/plugin/openai_vision/plugin.py +12 -13
- pygpt_net/provider/agents/openai/agent.py +5 -5
- pygpt_net/provider/agents/openai/agent_b2b.py +5 -5
- pygpt_net/provider/agents/openai/agent_planner.py +5 -6
- pygpt_net/provider/agents/openai/agent_with_experts.py +5 -5
- pygpt_net/provider/agents/openai/agent_with_experts_feedback.py +4 -4
- pygpt_net/provider/agents/openai/agent_with_feedback.py +4 -4
- pygpt_net/provider/agents/openai/bot_researcher.py +2 -2
- pygpt_net/provider/agents/openai/bots/research_bot/agents/planner_agent.py +1 -1
- pygpt_net/provider/agents/openai/bots/research_bot/agents/search_agent.py +1 -1
- pygpt_net/provider/agents/openai/bots/research_bot/agents/writer_agent.py +1 -1
- pygpt_net/provider/agents/openai/evolve.py +5 -5
- pygpt_net/provider/agents/openai/supervisor.py +4 -4
- pygpt_net/provider/api/__init__.py +27 -0
- pygpt_net/provider/api/anthropic/__init__.py +68 -0
- pygpt_net/provider/api/google/__init__.py +295 -0
- pygpt_net/provider/api/google/audio.py +121 -0
- pygpt_net/provider/api/google/chat.py +591 -0
- pygpt_net/provider/api/google/image.py +427 -0
- 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/tools.py +222 -0
- pygpt_net/provider/api/google/vision.py +129 -0
- pygpt_net/provider/{gpt → api/openai}/__init__.py +24 -4
- pygpt_net/provider/api/openai/agents/__init__.py +0 -0
- pygpt_net/provider/{gpt → api/openai}/agents/computer.py +1 -1
- pygpt_net/provider/{gpt → api/openai}/agents/experts.py +1 -1
- pygpt_net/provider/{gpt → api/openai}/agents/response.py +1 -1
- pygpt_net/provider/{gpt → api/openai}/assistants.py +1 -1
- pygpt_net/provider/{gpt → api/openai}/chat.py +15 -8
- pygpt_net/provider/{gpt → api/openai}/completion.py +1 -1
- pygpt_net/provider/{gpt → api/openai}/image.py +1 -1
- 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 +194 -0
- pygpt_net/provider/{gpt → api/openai}/remote_tools.py +1 -1
- pygpt_net/provider/{gpt → api/openai}/responses.py +34 -20
- pygpt_net/provider/{gpt → api/openai}/store.py +2 -2
- pygpt_net/provider/{gpt → api/openai}/vision.py +1 -1
- pygpt_net/provider/api/openai/worker/__init__.py +0 -0
- pygpt_net/provider/{gpt → api/openai}/worker/assistants.py +4 -4
- pygpt_net/provider/{gpt → api/openai}/worker/importer.py +10 -10
- pygpt_net/provider/audio_input/google_genai.py +103 -0
- pygpt_net/provider/audio_input/openai_whisper.py +1 -1
- pygpt_net/provider/audio_output/google_genai_tts.py +229 -0
- pygpt_net/provider/audio_output/openai_tts.py +9 -6
- pygpt_net/provider/core/config/patch.py +26 -0
- pygpt_net/provider/core/model/patch.py +20 -0
- pygpt_net/provider/core/preset/json_file.py +2 -4
- pygpt_net/provider/llms/anthropic.py +2 -5
- pygpt_net/provider/llms/base.py +4 -3
- pygpt_net/provider/llms/google.py +8 -9
- pygpt_net/provider/llms/openai.py +1 -1
- pygpt_net/provider/loaders/hub/image_vision/base.py +1 -1
- pygpt_net/ui/dialog/preset.py +71 -55
- pygpt_net/ui/layout/toolbox/footer.py +16 -0
- pygpt_net/ui/layout/toolbox/image.py +5 -0
- pygpt_net/ui/main.py +6 -4
- pygpt_net/ui/widget/option/combo.py +15 -1
- pygpt_net/utils.py +9 -0
- {pygpt_net-2.6.29.dist-info → pygpt_net-2.6.31.dist-info}/METADATA +55 -55
- {pygpt_net-2.6.29.dist-info → pygpt_net-2.6.31.dist-info}/RECORD +181 -135
- pygpt_net/core/audio/backend/pyaudio.py +0 -554
- /pygpt_net/{provider/gpt/agents → controller/chat/handler}/__init__.py +0 -0
- /pygpt_net/{provider/gpt/worker → core/realtime}/__init__.py +0 -0
- /pygpt_net/provider/{gpt → api/openai}/agents/client.py +0 -0
- /pygpt_net/provider/{gpt → api/openai}/agents/remote_tools.py +0 -0
- /pygpt_net/provider/{gpt → api/openai}/agents/utils.py +0 -0
- /pygpt_net/provider/{gpt → api/openai}/audio.py +0 -0
- /pygpt_net/provider/{gpt → api/openai}/computer.py +0 -0
- /pygpt_net/provider/{gpt → api/openai}/container.py +0 -0
- /pygpt_net/provider/{gpt → api/openai}/summarizer.py +0 -0
- /pygpt_net/provider/{gpt → api/openai}/tools.py +0 -0
- /pygpt_net/provider/{gpt → api/openai}/utils.py +0 -0
- {pygpt_net-2.6.29.dist-info → pygpt_net-2.6.31.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.29.dist-info → pygpt_net-2.6.31.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.29.dist-info → pygpt_net-2.6.31.dist-info}/entry_points.txt +0 -0
pygpt_net/CHANGELOG.txt
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
2.6.31 (2025-09-01)
|
|
2
|
+
|
|
3
|
+
- Chat with Audio mode renamed to Realtime + audio.
|
|
4
|
+
- Added support for real-time audio models from OpenAI (Realtime API) and Google (Live API), featuring real-time audio integration (beta).
|
|
5
|
+
- Introduced new predefined models: gpt-realtime, gpt-4o-realtime-preview, and gemini-2.5-flash-preview-native-audio-dialog.
|
|
6
|
+
- Included Google Gen AI audio input and output providers in the Audio Input/Output plugins.
|
|
7
|
+
- Added URL Context remote tool support in Google Gen AI.
|
|
8
|
+
|
|
9
|
+
2.6.30 (2025-08-29)
|
|
10
|
+
|
|
11
|
+
- Added native Google GenAI API support (beta); live audio is not supported yet (#132).
|
|
12
|
+
- Added new predefined models for image generation: Google Imagen3 and Imagen4.
|
|
13
|
+
- Optimized token usage in the Responses API.
|
|
14
|
+
- Removed Vision mode (it is now integrated into Chat).
|
|
15
|
+
|
|
1
16
|
2.6.29 (2025-08-28)
|
|
2
17
|
|
|
3
18
|
- Verbose options have been moved to the Developer section in settings.
|
pygpt_net/__init__.py
CHANGED
|
@@ -6,15 +6,15 @@
|
|
|
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.09.01 00:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
__author__ = "Marcin Szczygliński"
|
|
13
13
|
__copyright__ = "Copyright 2025, Marcin Szczygliński"
|
|
14
14
|
__credits__ = ["Marcin Szczygliński"]
|
|
15
15
|
__license__ = "MIT"
|
|
16
|
-
__version__ = "2.6.
|
|
17
|
-
__build__ = "2025-
|
|
16
|
+
__version__ = "2.6.31"
|
|
17
|
+
__build__ = "2025-09-01"
|
|
18
18
|
__maintainer__ = "Marcin Szczygliński"
|
|
19
19
|
__github__ = "https://github.com/szczyglis-dev/py-gpt"
|
|
20
20
|
__report__ = "https://github.com/szczyglis-dev/py-gpt/issues"
|
pygpt_net/app.py
CHANGED
|
@@ -171,10 +171,12 @@ from pygpt_net.provider.audio_input.openai_whisper import OpenAIWhisper
|
|
|
171
171
|
from pygpt_net.provider.audio_input.openai_whisper_local import OpenAIWhisperLocal
|
|
172
172
|
from pygpt_net.provider.audio_input.google_speech_recognition import GoogleSpeechRecognition
|
|
173
173
|
from pygpt_net.provider.audio_input.google_cloud_speech_recognition import GoogleCloudSpeechRecognition
|
|
174
|
+
from pygpt_net.provider.audio_input.google_genai import GoogleGenAIAudioInput
|
|
174
175
|
from pygpt_net.provider.audio_input.bing_speech_recognition import BingSpeechRecognition
|
|
175
176
|
from pygpt_net.provider.audio_output.openai_tts import OpenAITextToSpeech
|
|
176
177
|
from pygpt_net.provider.audio_output.ms_azure_tts import MSAzureTextToSpeech
|
|
177
178
|
from pygpt_net.provider.audio_output.google_tts import GoogleTextToSpeech
|
|
179
|
+
from pygpt_net.provider.audio_output.google_genai_tts import GoogleGenAITextToSpeech
|
|
178
180
|
from pygpt_net.provider.audio_output.eleven_labs import ElevenLabsTextToSpeech
|
|
179
181
|
|
|
180
182
|
# web search engine providers
|
|
@@ -318,10 +320,12 @@ def run(**kwargs):
|
|
|
318
320
|
launcher.add_audio_input(OpenAIWhisperLocal())
|
|
319
321
|
launcher.add_audio_input(GoogleSpeechRecognition())
|
|
320
322
|
launcher.add_audio_input(GoogleCloudSpeechRecognition())
|
|
323
|
+
launcher.add_audio_input(GoogleGenAIAudioInput())
|
|
321
324
|
launcher.add_audio_input(BingSpeechRecognition())
|
|
322
325
|
launcher.add_audio_output(OpenAITextToSpeech())
|
|
323
326
|
launcher.add_audio_output(MSAzureTextToSpeech())
|
|
324
327
|
launcher.add_audio_output(GoogleTextToSpeech())
|
|
328
|
+
launcher.add_audio_output(GoogleGenAITextToSpeech())
|
|
325
329
|
launcher.add_audio_output(ElevenLabsTextToSpeech())
|
|
326
330
|
|
|
327
331
|
# register custom audio providers
|
|
@@ -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.08.
|
|
9
|
+
# Updated Date: 2025.08.28 09:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from pygpt_net.config import Config
|
|
@@ -45,21 +45,21 @@ from pygpt_net.core.tokens import Tokens
|
|
|
45
45
|
from pygpt_net.core.updater import Updater
|
|
46
46
|
from pygpt_net.core.vision import Vision
|
|
47
47
|
from pygpt_net.core.web import Web
|
|
48
|
-
from pygpt_net.provider.gpt import Gpt
|
|
49
48
|
|
|
49
|
+
from pygpt_net.provider.api import Api
|
|
50
50
|
|
|
51
|
-
class
|
|
51
|
+
class Core:
|
|
52
52
|
def __init__(self, window=None):
|
|
53
53
|
"""
|
|
54
|
-
|
|
54
|
+
App core
|
|
55
55
|
|
|
56
56
|
:param window: Window instance
|
|
57
57
|
"""
|
|
58
58
|
self.window = window
|
|
59
59
|
|
|
60
|
-
# core
|
|
61
60
|
self.access = Access(window)
|
|
62
61
|
self.agents = Agents(window)
|
|
62
|
+
self.api = Api(window)
|
|
63
63
|
self.assistants = Assistants(window)
|
|
64
64
|
self.attachments = Attachments(window)
|
|
65
65
|
self.audio = Audio(window)
|
|
@@ -75,7 +75,6 @@ class Container:
|
|
|
75
75
|
self.dispatcher = Dispatcher(window)
|
|
76
76
|
self.experts = Experts(window)
|
|
77
77
|
self.filesystem = Filesystem(window)
|
|
78
|
-
self.gpt = Gpt(window)
|
|
79
78
|
self.history = History(window)
|
|
80
79
|
self.idx = Idx(window)
|
|
81
80
|
self.image = Image(window)
|
pygpt_net/controller/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
# ================================================== #
|
|
4
4
|
# This file is a part of PYGPT package #
|
|
@@ -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.08.
|
|
9
|
+
# Updated Date: 2025.08.30 06:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from pygpt_net.controller.access import Access
|
|
@@ -34,6 +34,7 @@ from pygpt_net.controller.model import Model
|
|
|
34
34
|
from pygpt_net.controller.notepad import Notepad
|
|
35
35
|
from pygpt_net.controller.painter import Painter
|
|
36
36
|
from pygpt_net.controller.plugins import Plugins
|
|
37
|
+
from pygpt_net.controller.realtime import Realtime
|
|
37
38
|
from pygpt_net.controller.presets import Presets
|
|
38
39
|
from pygpt_net.controller.settings import Settings
|
|
39
40
|
from pygpt_net.controller.theme import Theme
|
|
@@ -76,6 +77,7 @@ class Controller:
|
|
|
76
77
|
self.painter = Painter(window)
|
|
77
78
|
self.plugins = Plugins(window)
|
|
78
79
|
self.presets = Presets(window)
|
|
80
|
+
self.realtime = Realtime(window)
|
|
79
81
|
self.settings = Settings(window)
|
|
80
82
|
self.theme = Theme(window)
|
|
81
83
|
self.tools = Tools(window)
|
|
@@ -108,6 +110,7 @@ class Controller:
|
|
|
108
110
|
self.attachment.setup()
|
|
109
111
|
self.camera.setup_ui()
|
|
110
112
|
self.access.setup()
|
|
113
|
+
self.realtime.setup()
|
|
111
114
|
|
|
112
115
|
def post_setup(self):
|
|
113
116
|
"""Post-setup, after plugins are loaded"""
|
|
@@ -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: 2025.08.28 09:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import re
|
|
@@ -14,16 +14,8 @@ import re
|
|
|
14
14
|
from PySide6.QtCore import QTimer
|
|
15
15
|
|
|
16
16
|
from pygpt_net.core.types import (
|
|
17
|
-
MODE_AGENT,
|
|
18
|
-
MODE_AGENT_LLAMA,
|
|
19
|
-
MODE_ASSISTANT,
|
|
20
17
|
MODE_CHAT,
|
|
21
|
-
MODE_COMPLETION,
|
|
22
|
-
MODE_EXPERT,
|
|
23
|
-
MODE_LANGCHAIN,
|
|
24
18
|
MODE_LLAMA_INDEX,
|
|
25
|
-
MODE_VISION,
|
|
26
|
-
MODE_IMAGE,
|
|
27
19
|
)
|
|
28
20
|
from pygpt_net.core.tabs.tab import Tab
|
|
29
21
|
from pygpt_net.core.events import ControlEvent
|
|
@@ -91,7 +91,7 @@ class Assistant:
|
|
|
91
91
|
|
|
92
92
|
# get status
|
|
93
93
|
try:
|
|
94
|
-
status = self.window.core.
|
|
94
|
+
status = self.window.core.api.openai.assistants.run_stop(ctx)
|
|
95
95
|
if status == "cancelling" or status == "cancelled":
|
|
96
96
|
print("Run has been canceled.")
|
|
97
97
|
self.threads.log("Run status: {}".format(status))
|
|
@@ -227,7 +227,7 @@ class Assistant:
|
|
|
227
227
|
assistant = self.window.core.assistants.create()
|
|
228
228
|
self.editor.assign_data(assistant)
|
|
229
229
|
try:
|
|
230
|
-
return self.window.core.
|
|
230
|
+
return self.window.core.api.openai.assistants.create(assistant)
|
|
231
231
|
except Exception as e:
|
|
232
232
|
self.window.core.debug.log(e)
|
|
233
233
|
self.window.ui.dialogs.alert(e)
|
|
@@ -240,7 +240,7 @@ class Assistant:
|
|
|
240
240
|
"""
|
|
241
241
|
self.editor.assign_data(assistant)
|
|
242
242
|
try:
|
|
243
|
-
return self.window.core.
|
|
243
|
+
return self.window.core.api.openai.assistants.update(assistant)
|
|
244
244
|
except Exception as e:
|
|
245
245
|
self.window.core.debug.log(e)
|
|
246
246
|
self.window.ui.dialogs.alert(e)
|
|
@@ -300,7 +300,7 @@ class Assistant:
|
|
|
300
300
|
|
|
301
301
|
# delete in API
|
|
302
302
|
try:
|
|
303
|
-
self.window.core.
|
|
303
|
+
self.window.core.api.openai.assistants.delete(id)
|
|
304
304
|
except Exception as e:
|
|
305
305
|
self.window.ui.dialogs.alert(e)
|
|
306
306
|
|
|
@@ -42,7 +42,7 @@ class Batch:
|
|
|
42
42
|
|
|
43
43
|
# run asynchronous
|
|
44
44
|
self.window.update_status("Importing assistants...please wait...")
|
|
45
|
-
self.window.core.
|
|
45
|
+
self.window.core.api.openai.assistants.importer.import_assistants()
|
|
46
46
|
|
|
47
47
|
def import_stores(self, force: bool = False):
|
|
48
48
|
"""
|
|
@@ -60,7 +60,7 @@ class Batch:
|
|
|
60
60
|
# run asynchronous
|
|
61
61
|
self.window.update_status("Importing vector stores...please wait...")
|
|
62
62
|
self.window.core.assistants.store.truncate() # clear all stores
|
|
63
|
-
self.window.core.
|
|
63
|
+
self.window.core.api.openai.assistants.importer.import_vector_stores()
|
|
64
64
|
self.window.controller.assistant.files.update()
|
|
65
65
|
self.window.controller.assistant.store.update()
|
|
66
66
|
|
|
@@ -140,7 +140,7 @@ class Batch:
|
|
|
140
140
|
# run asynchronous
|
|
141
141
|
self.window.update_status("Removing files...please wait...")
|
|
142
142
|
QApplication.processEvents()
|
|
143
|
-
self.window.core.
|
|
143
|
+
self.window.core.api.openai.assistants.importer.truncate_files() # remove all files from API
|
|
144
144
|
|
|
145
145
|
def truncate_store_files_by_idx(self, idx: int, force: bool = False):
|
|
146
146
|
"""
|
|
@@ -173,7 +173,7 @@ class Batch:
|
|
|
173
173
|
# run asynchronous
|
|
174
174
|
self.window.update_status("Removing files...please wait...")
|
|
175
175
|
QApplication.processEvents()
|
|
176
|
-
self.window.core.
|
|
176
|
+
self.window.core.api.openai.assistants.importer.truncate_files(store_id) # remove all files from API
|
|
177
177
|
|
|
178
178
|
def clear_store_files_by_idx(
|
|
179
179
|
self,
|
|
@@ -277,7 +277,7 @@ class Batch:
|
|
|
277
277
|
self.window.update_status("Removing vector stores...please wait...")
|
|
278
278
|
QApplication.processEvents()
|
|
279
279
|
self.window.core.assistants.store.truncate() # clear all stores
|
|
280
|
-
self.window.core.
|
|
280
|
+
self.window.core.api.openai.assistants.importer.truncate_vector_stores()
|
|
281
281
|
self.window.controller.assistant.files.update()
|
|
282
282
|
self.window.controller.assistant.store.update()
|
|
283
283
|
self.window.controller.assistant.store.current = None
|
|
@@ -298,7 +298,7 @@ class Batch:
|
|
|
298
298
|
return
|
|
299
299
|
self.window.update_status("Refreshing vector stores...please wait...")
|
|
300
300
|
QApplication.processEvents()
|
|
301
|
-
self.window.core.
|
|
301
|
+
self.window.core.api.openai.assistants.importer.refresh_vector_stores()
|
|
302
302
|
|
|
303
303
|
def handle_imported_assistants(self, num: int):
|
|
304
304
|
"""
|
|
@@ -539,7 +539,7 @@ class Batch:
|
|
|
539
539
|
store_id = self.window.controller.assistant.store.current
|
|
540
540
|
self.window.update_status("Uploading files...please wait...")
|
|
541
541
|
QApplication.processEvents()
|
|
542
|
-
self.window.core.
|
|
542
|
+
self.window.core.api.openai.assistants.importer.upload_files(store_id, self.files_to_upload)
|
|
543
543
|
self.files_to_upload = [] # clear files
|
|
544
544
|
|
|
545
545
|
def handle_uploaded_files(self, num: int):
|
|
@@ -75,7 +75,7 @@ class Files:
|
|
|
75
75
|
"""
|
|
76
76
|
# run asynchronous
|
|
77
77
|
self.window.update_status("Importing files...please wait...")
|
|
78
|
-
self.window.core.
|
|
78
|
+
self.window.core.api.openai.assistants.importer.import_files(store_id)
|
|
79
79
|
|
|
80
80
|
def download(self, idx: int):
|
|
81
81
|
"""
|
|
@@ -276,7 +276,7 @@ class Files:
|
|
|
276
276
|
continue
|
|
277
277
|
|
|
278
278
|
# upload local attachment file and get new ID (file_id)
|
|
279
|
-
new_id = self.window.core.
|
|
279
|
+
new_id = self.window.core.api.openai.store.upload(
|
|
280
280
|
attachment.path,
|
|
281
281
|
)
|
|
282
282
|
if new_id is not None:
|
|
@@ -287,14 +287,14 @@ class Files:
|
|
|
287
287
|
|
|
288
288
|
"""
|
|
289
289
|
if assistant.vector_store is None or assistant.vector_store == "":
|
|
290
|
-
assistant.vector_store = self.window.core.
|
|
290
|
+
assistant.vector_store = self.window.core.api.openai.store.create_store(
|
|
291
291
|
"thread-" + thread_id,
|
|
292
292
|
)
|
|
293
293
|
"""
|
|
294
294
|
|
|
295
295
|
# add to vector store if defined in assistant, otherwise file will be added to thread store
|
|
296
296
|
if assistant.vector_store:
|
|
297
|
-
self.window.core.
|
|
297
|
+
self.window.core.api.openai.store.add_file(
|
|
298
298
|
assistant.vector_store,
|
|
299
299
|
new_id,
|
|
300
300
|
)
|
|
@@ -42,7 +42,7 @@ class Threads(QObject):
|
|
|
42
42
|
|
|
43
43
|
:return: thread id
|
|
44
44
|
"""
|
|
45
|
-
thread_id = self.window.core.
|
|
45
|
+
thread_id = self.window.core.api.openai.assistants.thread_create()
|
|
46
46
|
self.window.core.config.set('assistant_thread', thread_id)
|
|
47
47
|
self.window.core.ctx.append_thread(thread_id)
|
|
48
48
|
return thread_id
|
|
@@ -245,7 +245,7 @@ class Threads(QObject):
|
|
|
245
245
|
|
|
246
246
|
:param ctx: CtxItem
|
|
247
247
|
"""
|
|
248
|
-
data = self.window.core.
|
|
248
|
+
data = self.window.core.api.openai.assistants.msg_list(ctx.thread)
|
|
249
249
|
for msg in data:
|
|
250
250
|
if msg.role == "assistant":
|
|
251
251
|
try:
|
|
@@ -640,7 +640,7 @@ class RunWorker(QRunnable):
|
|
|
640
640
|
while self.check \
|
|
641
641
|
and not self.window.is_closing \
|
|
642
642
|
and not self.window.controller.assistant.threads.stop:
|
|
643
|
-
run = self.window.core.
|
|
643
|
+
run = self.window.core.api.openai.assistants.run_get(self.ctx)
|
|
644
644
|
status = None
|
|
645
645
|
if run is not None:
|
|
646
646
|
status = run.status
|
|
@@ -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.08.
|
|
9
|
+
# Updated Date: 2025.08.28 09:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -17,9 +17,6 @@ from urllib.parse import urlparse
|
|
|
17
17
|
from PySide6.QtGui import QImage
|
|
18
18
|
from PySide6.QtWidgets import QFileDialog, QApplication
|
|
19
19
|
|
|
20
|
-
from pygpt_net.core.types import (
|
|
21
|
-
MODE_VISION,
|
|
22
|
-
)
|
|
23
20
|
from pygpt_net.core.events import AppEvent, KernelEvent
|
|
24
21
|
from pygpt_net.item.attachment import AttachmentItem
|
|
25
22
|
from pygpt_net.item.ctx import CtxItem
|
|
@@ -73,7 +70,7 @@ class Attachment:
|
|
|
73
70
|
if not self.has(mode):
|
|
74
71
|
self.window.controller.chat.vision.unavailable()
|
|
75
72
|
else:
|
|
76
|
-
if
|
|
73
|
+
if self.window.controller.chat.vision.allowed():
|
|
77
74
|
self.window.controller.chat.vision.available()
|
|
78
75
|
|
|
79
76
|
# update tokens counter (vision plugin, etc.)
|
|
@@ -480,7 +477,7 @@ class Attachment:
|
|
|
480
477
|
"""
|
|
481
478
|
try:
|
|
482
479
|
# get file info from assistant API
|
|
483
|
-
data = self.window.core.
|
|
480
|
+
data = self.window.core.api.openai.store.get_file(file_id)
|
|
484
481
|
if data is None:
|
|
485
482
|
return
|
|
486
483
|
|
|
@@ -506,7 +503,7 @@ class Attachment:
|
|
|
506
503
|
path = self.get_download_path(filename)
|
|
507
504
|
|
|
508
505
|
# download file
|
|
509
|
-
self.window.core.
|
|
506
|
+
self.window.core.api.openai.store.download(
|
|
510
507
|
file_id=file_id,
|
|
511
508
|
path=path,
|
|
512
509
|
)
|
|
@@ -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.08.
|
|
9
|
+
# Updated Date: 2025.08.31 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -43,6 +43,30 @@ class Audio:
|
|
|
43
43
|
if self.window.core.config.get("audio.input.continuous", False):
|
|
44
44
|
self.window.ui.plugin_addon['audio.input.btn'].continuous.setChecked(True)
|
|
45
45
|
|
|
46
|
+
if self.window.core.config.get("audio.input.auto_turn", False):
|
|
47
|
+
self.window.ui.nodes['audio.auto_turn'].box.setChecked(True)
|
|
48
|
+
|
|
49
|
+
def execute_input_stop(self):
|
|
50
|
+
"""Execute input stop (from UI)"""
|
|
51
|
+
self.window.dispatch(Event(Event.AUDIO_INPUT_RECORD_TOGGLE, {
|
|
52
|
+
"state": False,
|
|
53
|
+
"auto": True, # do not emit manual event
|
|
54
|
+
}))
|
|
55
|
+
|
|
56
|
+
def is_recording(self) -> bool:
|
|
57
|
+
"""
|
|
58
|
+
Check if audio input is recording
|
|
59
|
+
|
|
60
|
+
:return: True if recording
|
|
61
|
+
"""
|
|
62
|
+
return self.window.core.plugins.get("audio_input").is_recording()
|
|
63
|
+
|
|
64
|
+
def toggle_auto_turn(self):
|
|
65
|
+
"""Toggle auto turn setting"""
|
|
66
|
+
value = self.window.ui.nodes['audio.auto_turn'].box.isChecked()
|
|
67
|
+
self.window.core.config.set("audio.input.auto_turn", value)
|
|
68
|
+
self.window.core.config.save()
|
|
69
|
+
|
|
46
70
|
def toggle_input(
|
|
47
71
|
self,
|
|
48
72
|
state: bool,
|
pygpt_net/controller/audio/ui.py
CHANGED
|
@@ -183,7 +183,7 @@ class UI:
|
|
|
183
183
|
"""
|
|
184
184
|
self.recording = True
|
|
185
185
|
self.window.ui.nodes['input'].set_icon_state("mic", True)
|
|
186
|
-
if mode
|
|
186
|
+
if mode in ["input", "realtime"]:
|
|
187
187
|
self.window.controller.chat.common.lock_input()
|
|
188
188
|
return
|
|
189
189
|
btn = self.get_input_btn() if mode == 'input' else self.get_input_control_btn()
|
|
@@ -198,7 +198,7 @@ class UI:
|
|
|
198
198
|
"""
|
|
199
199
|
self.recording = False
|
|
200
200
|
self.window.ui.nodes['input'].set_icon_state("mic", False)
|
|
201
|
-
if mode
|
|
201
|
+
if mode in ["input", "realtime"]:
|
|
202
202
|
self.window.controller.chat.common.unlock_input()
|
|
203
203
|
return
|
|
204
204
|
btn = self.get_input_btn() if mode == 'input' else self.get_input_control_btn()
|
|
@@ -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: 2025.08.30 06:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import base64
|
|
@@ -40,19 +40,12 @@ class Audio:
|
|
|
40
40
|
"""Update input/output audio"""
|
|
41
41
|
mode = self.window.core.config.get("mode")
|
|
42
42
|
if mode == MODE_AUDIO:
|
|
43
|
-
if not self.window.controller.audio.is_output_enabled():
|
|
44
|
-
self.window.controller.audio.enable_output()
|
|
45
|
-
self.tmp_output = True
|
|
46
|
-
else:
|
|
47
|
-
self.tmp_output = False
|
|
48
43
|
if not self.window.controller.audio.is_input_enabled():
|
|
49
44
|
self.window.controller.audio.enable_input()
|
|
50
45
|
self.tmp_input = True
|
|
51
46
|
else:
|
|
52
47
|
self.tmp_input = False
|
|
53
48
|
else:
|
|
54
|
-
if self.tmp_output:
|
|
55
|
-
self.window.controller.audio.disable_output()
|
|
56
49
|
if self.tmp_input:
|
|
57
50
|
self.window.controller.audio.disable_input()
|
|
58
51
|
|
|
@@ -10,12 +10,13 @@
|
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
13
|
+
from typing import Any
|
|
13
14
|
|
|
14
15
|
from PySide6.QtGui import QTextCursor
|
|
15
16
|
from PySide6.QtWidgets import QFileDialog, QApplication
|
|
16
17
|
|
|
17
18
|
from pygpt_net.core.events import Event, AppEvent, RenderEvent, KernelEvent
|
|
18
|
-
from pygpt_net.core.types import MODE_ASSISTANT
|
|
19
|
+
from pygpt_net.core.types import MODE_ASSISTANT, MODE_AUDIO
|
|
19
20
|
from pygpt_net.item.ctx import CtxItem
|
|
20
21
|
from pygpt_net.item.model import ModelItem
|
|
21
22
|
from pygpt_net.utils import trans
|
|
@@ -119,6 +120,17 @@ class Common:
|
|
|
119
120
|
else:
|
|
120
121
|
self.window.ui.config['global']['img_raw'].setChecked(False)
|
|
121
122
|
|
|
123
|
+
# image resolution
|
|
124
|
+
resolution = self.window.core.config.get('img_resolution', '1024x1024')
|
|
125
|
+
self.window.controller.config.apply_value(
|
|
126
|
+
parent_id="global",
|
|
127
|
+
key="img_resolution",
|
|
128
|
+
option=self.window.core.image.get_resolution_option(),
|
|
129
|
+
value=resolution,
|
|
130
|
+
)
|
|
131
|
+
if not self.initialized:
|
|
132
|
+
self.window.ui.add_hook("update.global.img_resolution", self.hook_update)
|
|
133
|
+
|
|
122
134
|
# set focus to input
|
|
123
135
|
self.window.ui.nodes['input'].setFocus()
|
|
124
136
|
self.initialized = True
|
|
@@ -257,7 +269,7 @@ class Common:
|
|
|
257
269
|
self.window.controller.access.voice.stop_recording(timeout=True)
|
|
258
270
|
|
|
259
271
|
if self.window.core.plugins.get("audio_input").handler_simple.is_recording:
|
|
260
|
-
self.window.
|
|
272
|
+
self.window.dispatch(Event(Event.AUDIO_INPUT_RECORD_TOGGLE))
|
|
261
273
|
return
|
|
262
274
|
|
|
263
275
|
# stop audio output if playing
|
|
@@ -275,7 +287,8 @@ class Common:
|
|
|
275
287
|
"""
|
|
276
288
|
# don't unlock input and leave stop btn if assistant mode or if agent/autonomous is enabled
|
|
277
289
|
# send btn will be unlocked in agent mode on stop
|
|
278
|
-
|
|
290
|
+
mode = self.window.core.config.get('mode')
|
|
291
|
+
if self.can_unlock(ctx) and mode != MODE_AUDIO:
|
|
279
292
|
if not self.window.controller.kernel.stopped():
|
|
280
293
|
self.unlock_input() # unlock input
|
|
281
294
|
return True
|
|
@@ -307,7 +320,7 @@ class Common:
|
|
|
307
320
|
controller.kernel.halt = True
|
|
308
321
|
dispatch(RenderEvent(RenderEvent.TOOL_END)) # show waiting
|
|
309
322
|
|
|
310
|
-
core.
|
|
323
|
+
core.api.openai.stop()
|
|
311
324
|
self.unlock_input()
|
|
312
325
|
|
|
313
326
|
controller.chat.input.generating = False
|
|
@@ -452,6 +465,19 @@ class Common:
|
|
|
452
465
|
else:
|
|
453
466
|
self.img_enable_raw()
|
|
454
467
|
|
|
468
|
+
def hook_update(self, key: str, value: Any, caller, *args, **kwargs):
|
|
469
|
+
"""
|
|
470
|
+
Hook for updating image resolution
|
|
471
|
+
|
|
472
|
+
:param key: config key
|
|
473
|
+
:param value: new value
|
|
474
|
+
:param caller: caller object
|
|
475
|
+
"""
|
|
476
|
+
if key == "img_resolution":
|
|
477
|
+
if not value:
|
|
478
|
+
return
|
|
479
|
+
self.window.core.config.set('img_resolution', value)
|
|
480
|
+
|
|
455
481
|
def save_text(
|
|
456
482
|
self,
|
|
457
483
|
text: str,
|