pygpt-net 2.5.92__py3-none-any.whl → 2.5.94__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 +12 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +8 -2
- pygpt_net/container.py +3 -1
- pygpt_net/controller/chat/image.py +0 -3
- pygpt_net/controller/chat/response.py +5 -1
- pygpt_net/controller/config/field/slider.py +9 -5
- pygpt_net/controller/config/placeholder.py +11 -1
- pygpt_net/controller/ctx/ctx.py +23 -18
- pygpt_net/controller/dialogs/confirm.py +9 -1
- pygpt_net/controller/settings/editor.py +0 -6
- pygpt_net/controller/ui/tabs.py +2 -2
- pygpt_net/core/models/models.py +6 -1
- pygpt_net/core/render/web/body.py +67 -2
- pygpt_net/core/text/__init__.py +1 -0
- pygpt_net/core/text/text.py +59 -0
- pygpt_net/core/types/openai.py +14 -1
- pygpt_net/data/config/config.json +4 -4
- pygpt_net/data/config/models.json +406 -393
- pygpt_net/data/config/presets/agent_openai_b2b.json +54 -0
- pygpt_net/data/config/settings.json +16 -13
- pygpt_net/data/css/web-blocks.css +14 -0
- pygpt_net/data/css/web-blocks.dark.css +4 -0
- pygpt_net/data/css/web-blocks.light.css +4 -0
- pygpt_net/data/css/web-chatgpt.css +14 -0
- pygpt_net/data/css/web-chatgpt.dark.css +4 -0
- pygpt_net/data/css/web-chatgpt.light.css +4 -0
- pygpt_net/data/css/web-chatgpt_wide.css +14 -0
- pygpt_net/data/css/web-chatgpt_wide.dark.css +4 -0
- pygpt_net/data/css/web-chatgpt_wide.light.css +4 -0
- pygpt_net/data/languages.csv +186 -0
- pygpt_net/data/locale/locale.de.ini +26 -0
- pygpt_net/data/locale/locale.en.ini +28 -0
- pygpt_net/data/locale/locale.es.ini +26 -0
- pygpt_net/data/locale/locale.fr.ini +26 -0
- pygpt_net/data/locale/locale.it.ini +26 -0
- pygpt_net/data/locale/locale.pl.ini +28 -1
- pygpt_net/data/locale/locale.uk.ini +26 -0
- pygpt_net/data/locale/locale.zh.ini +26 -0
- pygpt_net/item/model.py +6 -14
- pygpt_net/provider/agents/openai/agent_b2b.py +391 -0
- pygpt_net/provider/core/config/patch.py +19 -1
- pygpt_net/provider/core/model/patch.py +34 -2
- pygpt_net/provider/core/preset/patch.py +17 -0
- pygpt_net/provider/gpt/__init__.py +4 -4
- pygpt_net/provider/gpt/summarizer.py +2 -2
- pygpt_net/provider/llms/hugging_face_router.py +132 -0
- pygpt_net/tools/code_interpreter/ui/html.py +2 -2
- pygpt_net/tools/translator/__init__.py +12 -0
- pygpt_net/tools/translator/tool.py +490 -0
- pygpt_net/tools/translator/ui/__init__.py +0 -0
- pygpt_net/tools/translator/ui/dialogs.py +144 -0
- pygpt_net/tools/translator/ui/widgets.py +483 -0
- pygpt_net/ui/base/context_menu.py +18 -1
- pygpt_net/ui/dialog/image.py +0 -6
- pygpt_net/ui/widget/option/combo.py +2 -0
- pygpt_net/ui/widget/textarea/html.py +2 -2
- pygpt_net/ui/widget/textarea/web.py +3 -2
- {pygpt_net-2.5.92.dist-info → pygpt_net-2.5.94.dist-info}/METADATA +39 -26
- {pygpt_net-2.5.92.dist-info → pygpt_net-2.5.94.dist-info}/RECORD +63 -53
- {pygpt_net-2.5.92.dist-info → pygpt_net-2.5.94.dist-info}/LICENSE +0 -0
- {pygpt_net-2.5.92.dist-info → pygpt_net-2.5.94.dist-info}/WHEEL +0 -0
- {pygpt_net-2.5.92.dist-info → pygpt_net-2.5.94.dist-info}/entry_points.txt +0 -0
pygpt_net/CHANGELOG.txt
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
2.5.94 (2025-08-09)
|
|
2
|
+
|
|
3
|
+
- Added a new LLM provider: HuggingFace Router.
|
|
4
|
+
- Introduced a new model: gpt-oss (OpenAI open-source model available in HuggingFace and Ollama).
|
|
5
|
+
- Added a new agent mode in OpenAI Agents: Bot 2 Bot.
|
|
6
|
+
- Fixed: Storing the last used context ID when empty.
|
|
7
|
+
- Fixed: Reloading items when an agent run is stopped.
|
|
8
|
+
|
|
9
|
+
2.5.93 (2025-08-08)
|
|
10
|
+
|
|
11
|
+
- Added a new tool: Translate - in menu Tools - feature #123.
|
|
12
|
+
|
|
1
13
|
2.5.92 (2025-08-08)
|
|
2
14
|
|
|
3
15
|
- Added max files to store config option in Audio -> Cache.
|
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.08.
|
|
9
|
+
# Updated Date: 2025.08.09 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.5.
|
|
17
|
-
__build__ = "2025-08-
|
|
16
|
+
__version__ = "2.5.94"
|
|
17
|
+
__build__ = "2025-08-09"
|
|
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
|
@@ -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.09 01:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -16,7 +16,7 @@ import platform
|
|
|
16
16
|
|
|
17
17
|
# disable warnings
|
|
18
18
|
os.environ["TRANSFORMERS_NO_ADVISORY_WARNINGS"] = "1"
|
|
19
|
-
os.environ["QT_LOGGING_RULES"] = "qt.multimedia.ffmpeg=false"
|
|
19
|
+
os.environ["QT_LOGGING_RULES"] = "qt.multimedia.ffmpeg=false;qt.qpa.fonts=false"
|
|
20
20
|
|
|
21
21
|
if platform.system() == 'Windows':
|
|
22
22
|
# fix ffmpeg bug: [SWR] Output channel layout "" is invalid or unsupported.
|
|
@@ -85,6 +85,7 @@ from pygpt_net.provider.agents.openai.agent_with_feedback import Agent as OpenAI
|
|
|
85
85
|
from pygpt_net.provider.agents.openai.bot_researcher import Agent as OpenAIAgentBotResearcher
|
|
86
86
|
from pygpt_net.provider.agents.openai.agent_planner import Agent as OpenAIAgentPlanner
|
|
87
87
|
from pygpt_net.provider.agents.openai.evolve import Agent as OpenAIAgentsEvolve
|
|
88
|
+
from pygpt_net.provider.agents.openai.agent_b2b import Agent as OpenAIAgentsB2B
|
|
88
89
|
|
|
89
90
|
# LLM wrapper providers (langchain, llama-index, embeddings)
|
|
90
91
|
from pygpt_net.provider.llms.anthropic import AnthropicLLM
|
|
@@ -93,6 +94,7 @@ from pygpt_net.provider.llms.deepseek_api import DeepseekApiLLM
|
|
|
93
94
|
from pygpt_net.provider.llms.google import GoogleLLM
|
|
94
95
|
# from pygpt_net.provider.llms.hugging_face import HuggingFaceLLM
|
|
95
96
|
from pygpt_net.provider.llms.hugging_face_api import HuggingFaceApiLLM
|
|
97
|
+
from pygpt_net.provider.llms.hugging_face_router import HuggingFaceRouterLLM
|
|
96
98
|
from pygpt_net.provider.llms.local import LocalLLM
|
|
97
99
|
from pygpt_net.provider.llms.mistral import MistralAILLM
|
|
98
100
|
from pygpt_net.provider.llms.ollama import OllamaLLM
|
|
@@ -161,6 +163,7 @@ from pygpt_net.tools.image_viewer import ImageViewer as ImageViewerTool
|
|
|
161
163
|
from pygpt_net.tools.media_player import MediaPlayer as MediaPlayerTool
|
|
162
164
|
from pygpt_net.tools.text_editor import TextEditor as TextEditorTool
|
|
163
165
|
from pygpt_net.tools.html_canvas import HtmlCanvas as HtmlCanvasTool
|
|
166
|
+
from pygpt_net.tools.translator import Translator as TranslatorTool
|
|
164
167
|
|
|
165
168
|
def run(**kwargs):
|
|
166
169
|
"""
|
|
@@ -389,6 +392,7 @@ def run(**kwargs):
|
|
|
389
392
|
launcher.add_llm(GoogleLLM())
|
|
390
393
|
# launcher.add_llm(HuggingFaceLLM())
|
|
391
394
|
launcher.add_llm(HuggingFaceApiLLM())
|
|
395
|
+
launcher.add_llm(HuggingFaceRouterLLM())
|
|
392
396
|
launcher.add_llm(LocalLLM())
|
|
393
397
|
launcher.add_llm(MistralAILLM())
|
|
394
398
|
launcher.add_llm(OllamaLLM())
|
|
@@ -429,6 +433,7 @@ def run(**kwargs):
|
|
|
429
433
|
launcher.add_agent(OpenAIAgentBotResearcher()) # openai-agents
|
|
430
434
|
launcher.add_agent(OpenAIAgentsExpertsFeedback()) # openai-agents
|
|
431
435
|
launcher.add_agent(OpenAIAgentsEvolve()) # openai-agents
|
|
436
|
+
launcher.add_agent(OpenAIAgentsB2B()) # openai-agents
|
|
432
437
|
|
|
433
438
|
# register custom agents
|
|
434
439
|
agents = kwargs.get('agents', None)
|
|
@@ -444,6 +449,7 @@ def run(**kwargs):
|
|
|
444
449
|
launcher.add_tool(AudioTranscriberTool())
|
|
445
450
|
launcher.add_tool(CodeInterpreterTool())
|
|
446
451
|
launcher.add_tool(HtmlCanvasTool())
|
|
452
|
+
launcher.add_tool(TranslatorTool())
|
|
447
453
|
|
|
448
454
|
# register custom tools
|
|
449
455
|
tools = kwargs.get('tools', None)
|
pygpt_net/container.py
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.
|
|
9
|
+
# Updated Date: 2025.08.08 05:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from pygpt_net.config import Config
|
|
@@ -40,6 +40,7 @@ from pygpt_net.core.presets import Presets
|
|
|
40
40
|
from pygpt_net.core.prompt import Prompt
|
|
41
41
|
from pygpt_net.core.settings import Settings
|
|
42
42
|
from pygpt_net.core.tabs import Tabs
|
|
43
|
+
from pygpt_net.core.text import Text
|
|
43
44
|
from pygpt_net.core.tokens import Tokens
|
|
44
45
|
from pygpt_net.core.updater import Updater
|
|
45
46
|
from pygpt_net.core.vision import Vision
|
|
@@ -89,6 +90,7 @@ class Container:
|
|
|
89
90
|
self.prompt = Prompt(window)
|
|
90
91
|
self.settings = Settings(window)
|
|
91
92
|
self.tabs = Tabs(window)
|
|
93
|
+
self.text = Text(window)
|
|
92
94
|
self.tokens = Tokens(window)
|
|
93
95
|
self.updater = Updater(window)
|
|
94
96
|
self.vision = Vision(window)
|
|
@@ -149,9 +149,6 @@ class Image:
|
|
|
149
149
|
string += "[{}]({})".format(basename, path) + "\n"
|
|
150
150
|
i += 1
|
|
151
151
|
|
|
152
|
-
if self.window.core.config.get('img_dialog_open'):
|
|
153
|
-
self.window.tools.get("viewer").open_images(paths) # use viewer tool
|
|
154
|
-
|
|
155
152
|
if not self.window.core.config.get('img_raw'):
|
|
156
153
|
string += "\nPrompt: "
|
|
157
154
|
string += prompt
|
|
@@ -19,7 +19,7 @@ from pygpt_net.core.types import (
|
|
|
19
19
|
MODE_CHAT,
|
|
20
20
|
)
|
|
21
21
|
from pygpt_net.core.bridge.context import BridgeContext
|
|
22
|
-
from pygpt_net.core.events import RenderEvent, KernelEvent
|
|
22
|
+
from pygpt_net.core.events import RenderEvent, KernelEvent, AppEvent
|
|
23
23
|
from pygpt_net.item.ctx import CtxItem
|
|
24
24
|
from pygpt_net.utils import trans
|
|
25
25
|
|
|
@@ -172,6 +172,10 @@ class Response:
|
|
|
172
172
|
ctx.msg_id = None
|
|
173
173
|
self.window.core.ctx.add(ctx) # store context to prevent current output from being lost
|
|
174
174
|
self.window.controller.ctx.prepare_name(ctx) # summarize if not yet
|
|
175
|
+
|
|
176
|
+
# finish render
|
|
177
|
+
self.window.dispatch(AppEvent(AppEvent.CTX_END)) # app event
|
|
178
|
+
self.window.dispatch(RenderEvent(RenderEvent.RELOAD)) # reload chat window
|
|
175
179
|
return
|
|
176
180
|
|
|
177
181
|
# at first, handle previous context (user input) if not handled yet
|
|
@@ -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.08.08 21:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Any, Optional, Dict, Union
|
|
@@ -65,7 +65,8 @@ class Slider:
|
|
|
65
65
|
value = option["max"]
|
|
66
66
|
|
|
67
67
|
# update connected input field
|
|
68
|
-
self.window.ui.config[parent_id]
|
|
68
|
+
if parent_id in self.window.ui.config and key in self.window.ui.config[parent_id]:
|
|
69
|
+
self.window.ui.config[parent_id][key].input.setText(str(value))
|
|
69
70
|
|
|
70
71
|
slider_value = round(float(value) * multiplier, 0)
|
|
71
72
|
|
|
@@ -83,12 +84,15 @@ class Slider:
|
|
|
83
84
|
slider_value = option["min"] * multiplier
|
|
84
85
|
elif "max" in option and slider_value > option["max"] * multiplier:
|
|
85
86
|
slider_value = option["max"] * multiplier
|
|
86
|
-
|
|
87
|
+
|
|
88
|
+
if parent_id in self.window.ui.config and key in self.window.ui.config[parent_id]:
|
|
89
|
+
self.window.ui.config[parent_id][key].slider.setValue(slider_value)
|
|
87
90
|
|
|
88
91
|
# from value
|
|
89
92
|
else:
|
|
90
|
-
self.window.ui.config[parent_id]
|
|
91
|
-
|
|
93
|
+
if parent_id in self.window.ui.config and key in self.window.ui.config[parent_id]:
|
|
94
|
+
self.window.ui.config[parent_id][key].input.setText(str(value))
|
|
95
|
+
self.window.ui.config[parent_id][key].slider.setValue(slider_value)
|
|
92
96
|
|
|
93
97
|
def on_update(
|
|
94
98
|
self,
|
|
@@ -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.08 05:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Dict, Any, List
|
|
@@ -86,6 +86,8 @@ class Placeholder:
|
|
|
86
86
|
return self.get_modes(params)
|
|
87
87
|
elif id == "models":
|
|
88
88
|
return self.get_models(params)
|
|
89
|
+
elif id == "languages":
|
|
90
|
+
return self.get_languages()
|
|
89
91
|
elif id == "multimodal":
|
|
90
92
|
return self.get_multimodal(params)
|
|
91
93
|
elif id == "langchain_providers":
|
|
@@ -456,6 +458,14 @@ class Placeholder:
|
|
|
456
458
|
data.append({id: name})
|
|
457
459
|
return data
|
|
458
460
|
|
|
461
|
+
def get_languages(self) -> List[Dict[str, str]]:
|
|
462
|
+
"""
|
|
463
|
+
Get world languages list
|
|
464
|
+
|
|
465
|
+
:return: Languages placeholders list
|
|
466
|
+
"""
|
|
467
|
+
return self.window.core.text.get_language_choices()
|
|
468
|
+
|
|
459
469
|
def get_idx(self, params: dict = None) -> List[Dict[str, str]]:
|
|
460
470
|
"""
|
|
461
471
|
Get indexes placeholders list
|
pygpt_net/controller/ctx/ctx.py
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.08.
|
|
9
|
+
# Updated Date: 2025.08.08 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
import gc
|
|
12
12
|
from typing import Optional, List
|
|
@@ -15,7 +15,7 @@ from PySide6.QtCore import QModelIndex, QTimer
|
|
|
15
15
|
from PySide6.QtGui import QStandardItem
|
|
16
16
|
|
|
17
17
|
from pygpt_net.core.events import Event, AppEvent, RenderEvent
|
|
18
|
-
from pygpt_net.item.ctx import CtxItem
|
|
18
|
+
from pygpt_net.item.ctx import CtxItem, CtxMeta
|
|
19
19
|
|
|
20
20
|
from .common import Common
|
|
21
21
|
from .summarizer import Summarizer
|
|
@@ -283,12 +283,7 @@ class Ctx:
|
|
|
283
283
|
self.window.core.config.set('assistant_thread', None) # reset assistant thread id
|
|
284
284
|
self.update()
|
|
285
285
|
|
|
286
|
-
# render reset
|
|
287
|
-
data = {
|
|
288
|
-
"meta": meta,
|
|
289
|
-
}
|
|
290
|
-
event = RenderEvent(RenderEvent.FRESH, data)
|
|
291
|
-
self.window.dispatch(event)
|
|
286
|
+
self.fresh_output(meta) # render reset
|
|
292
287
|
|
|
293
288
|
if not force: # only if real click on new context button
|
|
294
289
|
self.window.controller.chat.common.unlock_input()
|
|
@@ -407,16 +402,7 @@ class Ctx:
|
|
|
407
402
|
|
|
408
403
|
# reset appended data / prepare new ctx
|
|
409
404
|
if meta is not None:
|
|
410
|
-
|
|
411
|
-
"meta": meta,
|
|
412
|
-
}
|
|
413
|
-
event = RenderEvent(RenderEvent.FRESH, data)
|
|
414
|
-
self.window.dispatch(event)
|
|
415
|
-
data = {
|
|
416
|
-
"meta": meta,
|
|
417
|
-
}
|
|
418
|
-
event = RenderEvent(RenderEvent.ON_LOAD, data)
|
|
419
|
-
self.window.dispatch(event)
|
|
405
|
+
self.fresh_output(meta) # render reset
|
|
420
406
|
|
|
421
407
|
self.reload_config()
|
|
422
408
|
|
|
@@ -1244,3 +1230,22 @@ class Ctx:
|
|
|
1244
1230
|
def clear_selected(self):
|
|
1245
1231
|
"""Clear selected list"""
|
|
1246
1232
|
self.selected = []
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
def fresh_output(self, meta: CtxMeta):
|
|
1236
|
+
"""
|
|
1237
|
+
Fresh output for new context
|
|
1238
|
+
|
|
1239
|
+
:param meta: CtxItem
|
|
1240
|
+
"""
|
|
1241
|
+
# render reset
|
|
1242
|
+
data = {
|
|
1243
|
+
"meta": meta,
|
|
1244
|
+
}
|
|
1245
|
+
event = RenderEvent(RenderEvent.FRESH, data)
|
|
1246
|
+
self.window.dispatch(event)
|
|
1247
|
+
data = {
|
|
1248
|
+
"meta": meta,
|
|
1249
|
+
}
|
|
1250
|
+
event = RenderEvent(RenderEvent.ON_LOAD, data)
|
|
1251
|
+
self.window.dispatch(event)
|
|
@@ -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.08.08 05:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Any, Optional
|
|
@@ -86,6 +86,14 @@ class Confirm:
|
|
|
86
86
|
elif type == 'html_canvas.clear':
|
|
87
87
|
self.window.tools.get("html_canvas").clear(force=True)
|
|
88
88
|
|
|
89
|
+
# translator
|
|
90
|
+
elif type == 'translator.clear':
|
|
91
|
+
self.window.tools.get("translator").clear(force=True)
|
|
92
|
+
elif type == 'translator.clear.left':
|
|
93
|
+
self.window.tools.get("translator").clear_left(force=True)
|
|
94
|
+
elif type == 'translator.clear.right':
|
|
95
|
+
self.window.tools.get("translator").clear_right(force=True)
|
|
96
|
+
|
|
89
97
|
# audio transcribe
|
|
90
98
|
elif type == 'audio.transcribe':
|
|
91
99
|
self.window.tools.get("transcriber").transcribe(id, force=True)
|
|
@@ -60,7 +60,6 @@ class Editor:
|
|
|
60
60
|
self.window.ui.add_hook("update.config.ctx.records.folders.top", self.hook_update)
|
|
61
61
|
self.window.ui.add_hook("update.config.layout.density", self.hook_update)
|
|
62
62
|
self.window.ui.add_hook("update.config.layout.tooltips", self.hook_update)
|
|
63
|
-
self.window.ui.add_hook("update.config.img_dialog_open", self.hook_update)
|
|
64
63
|
self.window.ui.add_hook("update.config.access.voice_control", self.hook_update)
|
|
65
64
|
self.window.ui.add_hook("update.config.debug", self.hook_update)
|
|
66
65
|
self.window.ui.add_hook("update.config.notepad.num", self.hook_update)
|
|
@@ -327,11 +326,6 @@ class Editor:
|
|
|
327
326
|
self.window.controller.theme.reload()
|
|
328
327
|
self.window.controller.theme.menu.update_density()
|
|
329
328
|
|
|
330
|
-
# toggle image dialog auto-open
|
|
331
|
-
elif key == "img_dialog_open":
|
|
332
|
-
self.window.core.config.set(key, value)
|
|
333
|
-
self.window.ui.nodes['dialog.image.open.toggle'].setChecked(value)
|
|
334
|
-
|
|
335
329
|
# debug: menu
|
|
336
330
|
elif key == "debug":
|
|
337
331
|
self.window.core.config.set(key, value)
|
pygpt_net/controller/ui/tabs.py
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.08.
|
|
9
|
+
# Updated Date: 2025.08.08 23:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Any, Optional, Tuple
|
|
@@ -614,7 +614,7 @@ class Tabs:
|
|
|
614
614
|
:param name: new title
|
|
615
615
|
:param close: close dialog
|
|
616
616
|
"""
|
|
617
|
-
self.window.core.tabs.update_title(idx, name)
|
|
617
|
+
self.window.core.tabs.update_title(idx, name, name)
|
|
618
618
|
if close:
|
|
619
619
|
self.window.ui.dialog['rename'].close()
|
|
620
620
|
self.debug()
|
pygpt_net/core/models/models.py
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
|
7
7
|
# MIT License #
|
|
8
8
|
# Created By : Marcin Szczygliński #
|
|
9
|
-
# Updated Date: 2025.
|
|
9
|
+
# Updated Date: 2025.08.08 19:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import copy
|
|
@@ -527,6 +527,11 @@ class Models:
|
|
|
527
527
|
args["api_key"] = self.window.core.config.get('api_key_mistral', "")
|
|
528
528
|
args["base_url"] = self.window.core.config.get('api_endpoint_mistral', "")
|
|
529
529
|
self.window.core.debug.info("[api] Using client: Mistral AI API")
|
|
530
|
+
# HuggingFace Router
|
|
531
|
+
elif model.provider == "huggingface_router":
|
|
532
|
+
args["api_key"] = self.window.core.config.get('api_key_hugging_face', "")
|
|
533
|
+
args["base_url"] = self.window.core.config.get('api_endpoint_hugging_face', "")
|
|
534
|
+
self.window.core.debug.info("[api] Using client: HuggingFace Router API")
|
|
530
535
|
else:
|
|
531
536
|
self.window.core.debug.info("[api] Using client: OpenAI (default)")
|
|
532
537
|
|
|
@@ -6,10 +6,11 @@
|
|
|
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.08 19:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
13
|
+
import random
|
|
13
14
|
from typing import Optional, List, Dict
|
|
14
15
|
|
|
15
16
|
from pygpt_net.core.events import Event
|
|
@@ -24,6 +25,8 @@ import pygpt_net.fonts_rc
|
|
|
24
25
|
|
|
25
26
|
class Body:
|
|
26
27
|
|
|
28
|
+
NUM_TIPS = 13
|
|
29
|
+
|
|
27
30
|
def __init__(self, window=None):
|
|
28
31
|
"""
|
|
29
32
|
HTML Body
|
|
@@ -402,12 +405,28 @@ class Body:
|
|
|
402
405
|
html += "</div>"
|
|
403
406
|
return html
|
|
404
407
|
|
|
408
|
+
def get_all_tips(self) -> str:
|
|
409
|
+
"""
|
|
410
|
+
Generuje listę wszystkich tipów jako elementy HTML,
|
|
411
|
+
tasuje je i zwraca jako string JSON.
|
|
412
|
+
"""
|
|
413
|
+
if not self.window.core.config.get("layout.tooltips", False):
|
|
414
|
+
return "[]"
|
|
415
|
+
tips_list = []
|
|
416
|
+
for i in range(1, self.NUM_TIPS + 1):
|
|
417
|
+
tip_html = "<p><b>" + trans("output.tips.prefix") + "</b>: " + trans("output.tips." + str(i)) + "</p>"
|
|
418
|
+
tips_list.append(tip_html)
|
|
419
|
+
random.shuffle(tips_list)
|
|
420
|
+
import json
|
|
421
|
+
return json.dumps(tips_list)
|
|
422
|
+
|
|
405
423
|
def get_html(self, pid: int) -> str:
|
|
406
424
|
"""
|
|
407
425
|
Build webview HTML code
|
|
408
426
|
|
|
409
427
|
:return: HTML code
|
|
410
428
|
"""
|
|
429
|
+
tips_json = self.get_all_tips()
|
|
411
430
|
classes = []
|
|
412
431
|
classes_str = ""
|
|
413
432
|
style = self.window.core.config.get("theme.style", "blocks")
|
|
@@ -449,6 +468,8 @@ class Body:
|
|
|
449
468
|
let domLastCodeBlock = null;
|
|
450
469
|
let domLastParagraphBlock = null;
|
|
451
470
|
let htmlBuffer = "";
|
|
471
|
+
let tips = """ + tips_json + """;
|
|
472
|
+
let tips_hidden = false;
|
|
452
473
|
|
|
453
474
|
history.scrollRestoration = "manual";
|
|
454
475
|
document.addEventListener('keydown', function(event) {
|
|
@@ -473,6 +494,7 @@ class Body:
|
|
|
473
494
|
}
|
|
474
495
|
function prepare() {
|
|
475
496
|
collapsed_idx = []; // clear collapsed code
|
|
497
|
+
hideTips();
|
|
476
498
|
}
|
|
477
499
|
function sanitize(content) {
|
|
478
500
|
var parser = new DOMParser();
|
|
@@ -494,6 +516,37 @@ class Body:
|
|
|
494
516
|
}
|
|
495
517
|
restoreCollapsedCode();
|
|
496
518
|
}
|
|
519
|
+
function hideTips() {
|
|
520
|
+
if (tips_hidden) return;
|
|
521
|
+
document.getElementById('tips').style.display = 'none';
|
|
522
|
+
tips_hidden = true;
|
|
523
|
+
}
|
|
524
|
+
function showTips() {
|
|
525
|
+
if (tips_hidden) return;
|
|
526
|
+
if (tips.length === 0) return;
|
|
527
|
+
document.getElementById('tips').style.display = 'block';
|
|
528
|
+
tips_hidden = false;
|
|
529
|
+
}
|
|
530
|
+
function cycleTips() {
|
|
531
|
+
if (tips_hidden) return;
|
|
532
|
+
if (tips.length === 0) return;
|
|
533
|
+
let tipContainer = document.getElementById('tips');
|
|
534
|
+
let currentTip = 0;
|
|
535
|
+
function showNextTip() {
|
|
536
|
+
if (tips_hidden) return;
|
|
537
|
+
tipContainer.innerHTML = tips[currentTip];
|
|
538
|
+
tipContainer.classList.add('visible');
|
|
539
|
+
setTimeout(function() {
|
|
540
|
+
if (tips_hidden) return;
|
|
541
|
+
tipContainer.classList.remove('visible');
|
|
542
|
+
setTimeout(function(){
|
|
543
|
+
currentTip = (currentTip + 1) % tips.length;
|
|
544
|
+
showNextTip();
|
|
545
|
+
}, 1000);
|
|
546
|
+
}, 10000);
|
|
547
|
+
}
|
|
548
|
+
showNextTip();
|
|
549
|
+
}
|
|
497
550
|
function renderMath() {
|
|
498
551
|
const scripts = document.querySelectorAll('script[type^="math/tex"]');
|
|
499
552
|
scripts.forEach(function(script) {
|
|
@@ -525,6 +578,7 @@ class Body:
|
|
|
525
578
|
scrollToBottom();
|
|
526
579
|
}
|
|
527
580
|
function appendToOutput(bot_name, content) {
|
|
581
|
+
hideTips();
|
|
528
582
|
const element = document.getElementById('_append_output_');
|
|
529
583
|
if (element) {
|
|
530
584
|
let box = element.querySelector('.msg-box');
|
|
@@ -564,6 +618,7 @@ class Body:
|
|
|
564
618
|
scrollToBottom();
|
|
565
619
|
}
|
|
566
620
|
function appendExtra(id, content) {
|
|
621
|
+
hideTips();
|
|
567
622
|
prevScroll = 0;
|
|
568
623
|
const element = document.getElementById('msg-bot-' + id);
|
|
569
624
|
if (element) {
|
|
@@ -619,6 +674,7 @@ class Body:
|
|
|
619
674
|
return element;
|
|
620
675
|
}
|
|
621
676
|
function clearStream() {
|
|
677
|
+
hideTips();
|
|
622
678
|
domLastParagraphBlock = null;
|
|
623
679
|
domLastCodeBlock = null;
|
|
624
680
|
domOutputStream = null;
|
|
@@ -649,12 +705,14 @@ class Body:
|
|
|
649
705
|
}
|
|
650
706
|
}
|
|
651
707
|
function beginStream() {
|
|
708
|
+
hideTips();
|
|
652
709
|
clearOutput();
|
|
653
710
|
}
|
|
654
711
|
function endStream() {
|
|
655
712
|
clearOutput();
|
|
656
713
|
}
|
|
657
714
|
function appendStream(bot_name, content, chunk, replace = false, is_code_block = false) {
|
|
715
|
+
hideTips();
|
|
658
716
|
const element = getStreamContainer();
|
|
659
717
|
doHighlight = true;
|
|
660
718
|
doMath = true;
|
|
@@ -742,6 +800,7 @@ class Body:
|
|
|
742
800
|
}
|
|
743
801
|
}
|
|
744
802
|
function replaceOutput(bot_name, content) {
|
|
803
|
+
hideTips();
|
|
745
804
|
const element = getStreamContainer();
|
|
746
805
|
if (element) {
|
|
747
806
|
let box = element.querySelector('.msg-box');
|
|
@@ -770,6 +829,7 @@ class Body:
|
|
|
770
829
|
scrollToBottom();
|
|
771
830
|
}
|
|
772
831
|
function nextStream() {
|
|
832
|
+
hideTips();
|
|
773
833
|
// Clear the current stream output and copy it to the before output
|
|
774
834
|
// 1. copy current output from _append_output_ to _append_output_before_
|
|
775
835
|
// 2. clear _append_output_
|
|
@@ -784,12 +844,14 @@ class Body:
|
|
|
784
844
|
}
|
|
785
845
|
}
|
|
786
846
|
function clearStreamBefore() {
|
|
847
|
+
hideTips();
|
|
787
848
|
const element = document.getElementById('_append_output_before_');
|
|
788
849
|
if (element) {
|
|
789
850
|
element.innerHTML = ''; // clear previous content
|
|
790
851
|
}
|
|
791
852
|
}
|
|
792
|
-
function replaceOutput(bot_name, content) {
|
|
853
|
+
function replaceOutput(bot_name, content) {
|
|
854
|
+
hideTips();
|
|
793
855
|
const element = getStreamContainer();
|
|
794
856
|
if (element) {
|
|
795
857
|
let box = element.querySelector('.msg-box');
|
|
@@ -1074,6 +1136,7 @@ class Body:
|
|
|
1074
1136
|
prevScroll = parseInt(pos);
|
|
1075
1137
|
}
|
|
1076
1138
|
function showLoading() {
|
|
1139
|
+
hideTips();
|
|
1077
1140
|
const el = document.getElementById('_loader_');
|
|
1078
1141
|
if (el) {
|
|
1079
1142
|
if (el.classList.contains('hidden')) {
|
|
@@ -1196,6 +1259,7 @@ class Body:
|
|
|
1196
1259
|
}
|
|
1197
1260
|
});
|
|
1198
1261
|
});
|
|
1262
|
+
setTimeout(cycleTips, 20000);
|
|
1199
1263
|
</script>
|
|
1200
1264
|
</head>
|
|
1201
1265
|
<body """ + classes_str + """>
|
|
@@ -1209,6 +1273,7 @@ class Body:
|
|
|
1209
1273
|
<div id="_loader_" class="loader-global hidden">
|
|
1210
1274
|
<div class="lds-ring"><div></div><div></div><div></div><div></div></div>
|
|
1211
1275
|
</div>
|
|
1276
|
+
<div id="tips" class="tips"></div>
|
|
1212
1277
|
</div>
|
|
1213
1278
|
</body>
|
|
1214
1279
|
</html>
|
pygpt_net/core/text/__init__.py
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .text import *
|
|
@@ -0,0 +1,59 @@
|
|
|
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.08.08 05:00:00 #
|
|
10
|
+
# ================================================== #
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Text:
|
|
15
|
+
def __init__(self, window=None):
|
|
16
|
+
"""
|
|
17
|
+
Text helpers
|
|
18
|
+
|
|
19
|
+
:param window: Window instance
|
|
20
|
+
"""
|
|
21
|
+
self.window = window
|
|
22
|
+
|
|
23
|
+
def get_language_choices(self) -> list:
|
|
24
|
+
"""
|
|
25
|
+
Get available language choices
|
|
26
|
+
|
|
27
|
+
:return: list of dictionaries with language codes and names
|
|
28
|
+
"""
|
|
29
|
+
choices = []
|
|
30
|
+
choices.append({"-": "--- AUTO DETECT ---"})
|
|
31
|
+
csv_path = os.path.join(self.window.core.config.get_app_path(), 'data', 'languages.csv')
|
|
32
|
+
if os.path.exists(csv_path):
|
|
33
|
+
with open(csv_path, 'r', encoding='utf-8') as file:
|
|
34
|
+
for line in file.readlines()[1:]:
|
|
35
|
+
parts = line.strip().split(',')
|
|
36
|
+
if len(parts) >= 4:
|
|
37
|
+
lang_code = parts[0].strip()
|
|
38
|
+
lang_name = parts[3].strip()
|
|
39
|
+
lang_orig_name = parts[4].strip()
|
|
40
|
+
name = f"{lang_name} ({lang_orig_name})" if lang_orig_name else lang_name
|
|
41
|
+
name = name.replace("'", "").replace('"', "")
|
|
42
|
+
choices.append({lang_code: name})
|
|
43
|
+
|
|
44
|
+
# sort choices by language name
|
|
45
|
+
choices.sort(key=lambda x: list(x.values())[0].lower())
|
|
46
|
+
return choices
|
|
47
|
+
|
|
48
|
+
def get_language_name(self, lang_code: str) -> str:
|
|
49
|
+
"""
|
|
50
|
+
Get language name by code
|
|
51
|
+
|
|
52
|
+
:param lang_code: language code
|
|
53
|
+
:return: language name or empty string if not found
|
|
54
|
+
"""
|
|
55
|
+
choices = self.get_language_choices()
|
|
56
|
+
for choice in choices:
|
|
57
|
+
if lang_code in choice:
|
|
58
|
+
return choice[lang_code]
|
|
59
|
+
return ""
|
pygpt_net/core/types/openai.py
CHANGED
|
@@ -6,9 +6,22 @@
|
|
|
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.08 19:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
|
+
OPENAI_COMPATIBLE_PROVIDERS = [
|
|
13
|
+
"anthropic",
|
|
14
|
+
"openai",
|
|
15
|
+
"azure_openai",
|
|
16
|
+
"google",
|
|
17
|
+
"huggingface_router",
|
|
18
|
+
"local_ai",
|
|
19
|
+
"mistral_ai",
|
|
20
|
+
"perplexity",
|
|
21
|
+
"deepseek_api",
|
|
22
|
+
"x_ai",
|
|
23
|
+
]
|
|
24
|
+
|
|
12
25
|
OPENAI_DISABLE_TOOLS = [
|
|
13
26
|
"o1-mini",
|
|
14
27
|
"o1-preview"
|