pygpt-net 2.4.37__py3-none-any.whl → 2.4.42__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.
- CHANGELOG.md +37 -0
- README.md +176 -182
- pygpt_net/CHANGELOG.txt +37 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +3 -1
- pygpt_net/controller/__init__.py +7 -3
- pygpt_net/controller/access/control.py +1 -1
- pygpt_net/controller/access/voice.py +11 -5
- pygpt_net/controller/agent/experts.py +11 -6
- pygpt_net/controller/agent/legacy.py +8 -6
- pygpt_net/controller/agent/llama.py +4 -2
- pygpt_net/controller/assistant/__init__.py +9 -4
- pygpt_net/controller/assistant/batch.py +38 -21
- pygpt_net/controller/assistant/editor.py +7 -6
- pygpt_net/controller/assistant/files.py +23 -7
- pygpt_net/controller/assistant/store.py +20 -7
- pygpt_net/controller/assistant/threads.py +34 -8
- pygpt_net/controller/attachment.py +29 -10
- pygpt_net/controller/audio/__init__.py +26 -5
- pygpt_net/controller/calendar/__init__.py +23 -4
- pygpt_net/controller/calendar/note.py +57 -11
- pygpt_net/controller/camera.py +4 -12
- pygpt_net/controller/chat/__init__.py +5 -3
- pygpt_net/controller/chat/attachment.py +34 -7
- pygpt_net/controller/chat/audio.py +2 -2
- pygpt_net/controller/chat/command.py +4 -2
- pygpt_net/controller/chat/common.py +11 -4
- pygpt_net/controller/chat/files.py +10 -3
- pygpt_net/controller/chat/image.py +17 -5
- pygpt_net/controller/chat/input.py +10 -7
- pygpt_net/controller/chat/output.py +21 -6
- pygpt_net/controller/chat/render.py +100 -21
- pygpt_net/controller/chat/response.py +34 -7
- pygpt_net/controller/chat/stream.py +4 -2
- pygpt_net/controller/chat/text.py +6 -4
- pygpt_net/controller/command.py +11 -3
- pygpt_net/controller/config/__init__.py +34 -6
- pygpt_net/controller/config/field/checkbox.py +7 -4
- pygpt_net/controller/config/field/cmd.py +7 -5
- pygpt_net/controller/config/field/combo.py +14 -6
- pygpt_net/controller/config/field/dictionary.py +14 -11
- pygpt_net/controller/config/field/input.py +9 -6
- pygpt_net/controller/config/field/slider.py +11 -8
- pygpt_net/controller/config/field/textarea.py +8 -5
- pygpt_net/controller/config/placeholder.py +66 -21
- pygpt_net/controller/ctx/__init__.py +138 -49
- pygpt_net/controller/ctx/common.py +15 -4
- pygpt_net/controller/ctx/extra.py +11 -3
- pygpt_net/controller/ctx/summarizer.py +24 -5
- pygpt_net/controller/debug/__init__.py +27 -6
- pygpt_net/controller/dialogs/confirm.py +34 -7
- pygpt_net/controller/dialogs/debug.py +4 -2
- pygpt_net/controller/dialogs/info.py +7 -2
- pygpt_net/controller/files.py +48 -10
- pygpt_net/controller/finder.py +11 -5
- pygpt_net/controller/idx/__init__.py +10 -3
- pygpt_net/controller/idx/common.py +4 -2
- pygpt_net/controller/idx/indexer.py +25 -17
- pygpt_net/controller/idx/settings.py +9 -3
- pygpt_net/controller/kernel/__init__.py +34 -8
- pygpt_net/controller/kernel/reply.py +12 -3
- pygpt_net/controller/kernel/stack.py +5 -3
- pygpt_net/controller/lang/custom.py +2 -7
- pygpt_net/controller/lang/mapping.py +5 -3
- pygpt_net/controller/layout.py +2 -2
- pygpt_net/controller/mode.py +16 -4
- pygpt_net/controller/model/__init__.py +14 -3
- pygpt_net/controller/model/editor.py +8 -3
- pygpt_net/controller/notepad.py +26 -12
- pygpt_net/controller/painter/capture.py +23 -4
- pygpt_net/controller/painter/common.py +9 -7
- pygpt_net/controller/plugins/__init__.py +19 -5
- pygpt_net/controller/plugins/presets.py +15 -6
- pygpt_net/controller/plugins/settings.py +9 -3
- pygpt_net/controller/presets/__init__.py +55 -16
- pygpt_net/controller/presets/editor.py +26 -10
- pygpt_net/controller/settings/__init__.py +3 -2
- pygpt_net/controller/settings/editor.py +29 -7
- pygpt_net/controller/settings/profile.py +22 -5
- pygpt_net/controller/theme/__init__.py +54 -12
- pygpt_net/controller/theme/common.py +24 -2
- pygpt_net/controller/theme/markdown.py +32 -16
- pygpt_net/controller/theme/menu.py +26 -5
- pygpt_net/controller/theme/nodes.py +2 -5
- pygpt_net/controller/tools/__init__.py +40 -2
- pygpt_net/controller/ui/__init__.py +4 -6
- pygpt_net/controller/ui/mode.py +16 -21
- pygpt_net/controller/ui/tabs.py +363 -65
- pygpt_net/core/access/actions.py +6 -4
- pygpt_net/core/access/shortcuts.py +4 -3
- pygpt_net/core/access/voice.py +6 -5
- pygpt_net/core/agents/legacy.py +4 -2
- pygpt_net/core/agents/memory.py +7 -2
- pygpt_net/core/agents/observer/evaluation.py +15 -7
- pygpt_net/core/agents/provider.py +9 -4
- pygpt_net/core/agents/runner.py +61 -15
- pygpt_net/core/agents/tools.py +23 -5
- pygpt_net/core/assistants/__init__.py +6 -4
- pygpt_net/core/assistants/files.py +35 -12
- pygpt_net/core/assistants/store.py +20 -10
- pygpt_net/core/attachments/__init__.py +54 -15
- pygpt_net/core/attachments/context.py +92 -29
- pygpt_net/core/audio/__init__.py +74 -3
- pygpt_net/core/audio/context.py +7 -2
- pygpt_net/core/audio/whisper.py +37 -0
- pygpt_net/core/bridge/__init__.py +22 -6
- pygpt_net/core/bridge/context.py +5 -3
- pygpt_net/core/bridge/worker.py +2 -2
- pygpt_net/core/calendar/__init__.py +57 -11
- pygpt_net/core/chain/__init__.py +8 -2
- pygpt_net/core/chain/chat.py +10 -8
- pygpt_net/core/chain/completion.py +10 -7
- pygpt_net/core/command.py +62 -17
- pygpt_net/core/ctx/__init__.py +260 -58
- pygpt_net/core/ctx/bag.py +25 -4
- pygpt_net/core/ctx/container.py +28 -17
- pygpt_net/core/ctx/idx.py +45 -8
- pygpt_net/core/ctx/output.py +95 -74
- pygpt_net/core/ctx/reply.py +5 -2
- pygpt_net/core/db/__init__.py +8 -7
- pygpt_net/core/db/viewer.py +17 -11
- pygpt_net/core/debug/__init__.py +10 -9
- pygpt_net/core/debug/events.py +22 -10
- pygpt_net/core/debug/tabs.py +9 -3
- pygpt_net/core/docker/__init__.py +11 -5
- pygpt_net/core/docker/builder.py +11 -3
- pygpt_net/core/events/app.py +5 -3
- pygpt_net/core/events/base.py +11 -5
- pygpt_net/core/events/control.py +5 -3
- pygpt_net/core/events/event.py +17 -7
- pygpt_net/core/events/kernel.py +5 -3
- pygpt_net/core/events/render.py +5 -3
- pygpt_net/core/experts/__init__.py +5 -4
- pygpt_net/core/filesystem/__init__.py +52 -34
- pygpt_net/core/filesystem/actions.py +8 -5
- pygpt_net/core/filesystem/editor.py +13 -3
- pygpt_net/core/filesystem/types.py +12 -7
- pygpt_net/core/filesystem/url.py +7 -3
- pygpt_net/core/history.py +3 -2
- pygpt_net/core/idx/__init__.py +48 -27
- pygpt_net/core/idx/chat.py +51 -17
- pygpt_net/core/idx/context.py +6 -2
- pygpt_net/core/idx/indexing.py +107 -42
- pygpt_net/core/idx/llm.py +11 -3
- pygpt_net/core/idx/metadata.py +13 -3
- pygpt_net/core/idx/types/ctx.py +32 -6
- pygpt_net/core/idx/types/external.py +41 -7
- pygpt_net/core/idx/types/files.py +31 -6
- pygpt_net/core/image.py +15 -4
- pygpt_net/core/installer.py +2 -4
- pygpt_net/core/llm/__init__.py +13 -3
- pygpt_net/core/locale.py +34 -8
- pygpt_net/core/models.py +63 -17
- pygpt_net/core/modes.py +11 -13
- pygpt_net/core/notepad.py +10 -5
- pygpt_net/core/plugins.py +31 -19
- pygpt_net/core/presets.py +37 -17
- pygpt_net/core/profile.py +21 -7
- pygpt_net/core/prompt/__init__.py +10 -3
- pygpt_net/core/prompt/custom.py +7 -6
- pygpt_net/core/prompt/template.py +9 -3
- pygpt_net/core/render/base.py +117 -22
- pygpt_net/core/render/markdown/body.py +27 -7
- pygpt_net/core/render/markdown/renderer.py +119 -22
- pygpt_net/core/render/plain/body.py +22 -5
- pygpt_net/core/render/plain/renderer.py +97 -21
- pygpt_net/core/render/web/body.py +75 -25
- pygpt_net/core/render/web/parser.py +3 -1
- pygpt_net/core/render/web/renderer.py +313 -63
- pygpt_net/core/settings.py +10 -5
- pygpt_net/core/tabs/__init__.py +290 -103
- pygpt_net/core/tabs/tab.py +26 -5
- pygpt_net/core/tokens.py +47 -12
- pygpt_net/core/updater/__init__.py +20 -7
- pygpt_net/core/vision/analyzer.py +29 -6
- pygpt_net/core/{web.py → web/__init__.py} +29 -7
- pygpt_net/core/web/helpers.py +237 -0
- pygpt_net/data/config/config.json +15 -4
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/modes.json +3 -3
- pygpt_net/data/config/settings.json +55 -10
- pygpt_net/data/config/settings_section.json +3 -0
- pygpt_net/data/css/style.light.css +1 -0
- pygpt_net/data/css/{web.css → web-blocks.css} +162 -133
- pygpt_net/data/css/{web.light.css → web-blocks.light.css} +7 -0
- pygpt_net/data/css/web-chatgpt.css +350 -0
- pygpt_net/data/css/web-chatgpt.dark.css +64 -0
- pygpt_net/data/css/web-chatgpt.light.css +75 -0
- pygpt_net/data/css/web-chatgpt_wide.css +350 -0
- pygpt_net/data/css/web-chatgpt_wide.dark.css +64 -0
- pygpt_net/data/css/web-chatgpt_wide.light.css +75 -0
- pygpt_net/data/icons/split_screen.svg +1 -0
- pygpt_net/data/locale/locale.de.ini +12 -0
- pygpt_net/data/locale/locale.en.ini +18 -2
- pygpt_net/data/locale/locale.es.ini +12 -0
- pygpt_net/data/locale/locale.fr.ini +12 -0
- pygpt_net/data/locale/locale.it.ini +12 -0
- pygpt_net/data/locale/locale.pl.ini +12 -0
- pygpt_net/data/locale/locale.uk.ini +12 -0
- pygpt_net/data/locale/locale.zh.ini +12 -0
- pygpt_net/data/locale/plugin.cmd_web.de.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.en.ini +22 -10
- pygpt_net/data/locale/plugin.cmd_web.es.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.fr.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.it.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.pl.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.uk.ini +2 -0
- pygpt_net/data/locale/plugin.cmd_web.zh.ini +2 -0
- pygpt_net/data/locale/plugin.mailer.en.ini +21 -0
- pygpt_net/icons.qrc +1 -0
- pygpt_net/icons_rc.py +165 -136
- pygpt_net/item/ctx.py +58 -25
- pygpt_net/plugin/agent/__init__.py +7 -2
- pygpt_net/plugin/audio_input/simple.py +21 -5
- pygpt_net/plugin/audio_output/__init__.py +9 -1
- pygpt_net/plugin/base/config.py +4 -2
- pygpt_net/plugin/base/plugin.py +75 -23
- pygpt_net/plugin/base/worker.py +42 -11
- pygpt_net/plugin/cmd_code_interpreter/__init__.py +39 -37
- pygpt_net/plugin/cmd_code_interpreter/runner.py +25 -12
- pygpt_net/plugin/cmd_history/config.py +2 -2
- pygpt_net/plugin/cmd_web/__init__.py +48 -9
- pygpt_net/plugin/cmd_web/config.py +135 -41
- pygpt_net/plugin/cmd_web/websearch.py +74 -33
- pygpt_net/plugin/cmd_web/worker.py +142 -13
- pygpt_net/plugin/idx_llama_index/config.py +3 -3
- pygpt_net/plugin/mailer/__init__.py +123 -0
- pygpt_net/plugin/mailer/config.py +149 -0
- pygpt_net/plugin/mailer/runner.py +285 -0
- pygpt_net/plugin/mailer/worker.py +123 -0
- pygpt_net/provider/agents/base.py +5 -2
- pygpt_net/provider/agents/openai.py +4 -2
- pygpt_net/provider/agents/openai_assistant.py +4 -2
- pygpt_net/provider/agents/planner.py +4 -2
- pygpt_net/provider/agents/react.py +4 -2
- pygpt_net/provider/audio_output/openai_tts.py +5 -11
- pygpt_net/provider/core/assistant/base.py +5 -3
- pygpt_net/provider/core/assistant/json_file.py +8 -5
- pygpt_net/provider/core/assistant_file/base.py +4 -3
- pygpt_net/provider/core/assistant_file/db_sqlite/__init__.py +4 -3
- pygpt_net/provider/core/assistant_file/db_sqlite/storage.py +3 -2
- pygpt_net/provider/core/assistant_store/base.py +6 -4
- pygpt_net/provider/core/assistant_store/db_sqlite/__init__.py +5 -4
- pygpt_net/provider/core/assistant_store/db_sqlite/storage.py +5 -3
- pygpt_net/provider/core/attachment/base.py +5 -3
- pygpt_net/provider/core/attachment/json_file.py +4 -3
- pygpt_net/provider/core/calendar/base.py +5 -3
- pygpt_net/provider/core/calendar/db_sqlite/__init__.py +6 -5
- pygpt_net/provider/core/calendar/db_sqlite/storage.py +5 -4
- pygpt_net/provider/core/config/base.py +8 -6
- pygpt_net/provider/core/config/json_file.py +9 -7
- pygpt_net/provider/core/config/patch.py +43 -1
- pygpt_net/provider/core/ctx/base.py +30 -25
- pygpt_net/provider/core/ctx/db_sqlite/__init__.py +59 -34
- pygpt_net/provider/core/ctx/db_sqlite/storage.py +62 -30
- pygpt_net/provider/core/ctx/db_sqlite/utils.py +11 -9
- pygpt_net/provider/core/index/base.py +129 -23
- pygpt_net/provider/core/index/db_sqlite/__init__.py +130 -23
- pygpt_net/provider/core/index/db_sqlite/storage.py +130 -23
- pygpt_net/provider/core/index/db_sqlite/utils.py +4 -2
- pygpt_net/provider/core/mode/base.py +5 -3
- pygpt_net/provider/core/mode/json_file.py +7 -6
- pygpt_net/provider/core/model/base.py +6 -4
- pygpt_net/provider/core/model/json_file.py +9 -7
- pygpt_net/provider/core/notepad/base.py +5 -3
- pygpt_net/provider/core/notepad/db_sqlite/__init__.py +5 -4
- pygpt_net/provider/core/notepad/db_sqlite/storage.py +4 -3
- pygpt_net/provider/core/plugin_preset/base.py +4 -2
- pygpt_net/provider/core/plugin_preset/json_file.py +5 -3
- pygpt_net/provider/core/preset/base.py +6 -4
- pygpt_net/provider/core/preset/json_file.py +9 -9
- pygpt_net/provider/core/prompt/base.py +6 -3
- pygpt_net/provider/core/prompt/json_file.py +11 -6
- pygpt_net/provider/gpt/assistants.py +21 -11
- pygpt_net/provider/gpt/audio.py +6 -5
- pygpt_net/provider/gpt/chat.py +10 -7
- pygpt_net/provider/gpt/completion.py +11 -5
- pygpt_net/provider/gpt/image.py +9 -2
- pygpt_net/provider/gpt/store.py +53 -18
- pygpt_net/provider/gpt/vision.py +17 -11
- pygpt_net/provider/llms/anthropic.py +7 -2
- pygpt_net/provider/llms/azure_openai.py +26 -5
- pygpt_net/provider/llms/base.py +47 -9
- pygpt_net/provider/llms/google.py +7 -2
- pygpt_net/provider/llms/hugging_face.py +13 -3
- pygpt_net/provider/llms/hugging_face_api.py +18 -4
- pygpt_net/provider/llms/local.py +7 -2
- pygpt_net/provider/llms/ollama.py +30 -6
- pygpt_net/provider/llms/openai.py +32 -6
- pygpt_net/provider/vector_stores/__init__.py +45 -14
- pygpt_net/provider/vector_stores/base.py +35 -8
- pygpt_net/provider/vector_stores/chroma.py +13 -3
- pygpt_net/provider/vector_stores/ctx_attachment.py +31 -12
- pygpt_net/provider/vector_stores/elasticsearch.py +12 -3
- pygpt_net/provider/vector_stores/pinecode.py +12 -3
- pygpt_net/provider/vector_stores/redis.py +12 -3
- pygpt_net/provider/vector_stores/simple.py +12 -3
- pygpt_net/provider/vector_stores/temp.py +16 -4
- pygpt_net/provider/web/base.py +10 -3
- pygpt_net/provider/web/google_custom_search.py +9 -3
- pygpt_net/provider/web/microsoft_bing.py +9 -3
- pygpt_net/tools/__init__.py +20 -4
- pygpt_net/tools/audio_transcriber/__init__.py +4 -3
- pygpt_net/tools/base.py +28 -7
- pygpt_net/tools/code_interpreter/__init__.py +177 -77
- pygpt_net/tools/code_interpreter/ui/dialogs.py +21 -103
- pygpt_net/tools/code_interpreter/ui/widgets.py +284 -9
- pygpt_net/tools/html_canvas/__init__.py +81 -25
- pygpt_net/tools/html_canvas/ui/dialogs.py +46 -62
- pygpt_net/tools/html_canvas/ui/widgets.py +96 -3
- pygpt_net/tools/image_viewer/__init__.py +10 -4
- pygpt_net/tools/indexer/__init__.py +8 -7
- pygpt_net/tools/media_player/__init__.py +4 -3
- pygpt_net/tools/text_editor/__init__.py +36 -10
- pygpt_net/ui/base/context_menu.py +2 -2
- pygpt_net/ui/layout/chat/input.py +10 -18
- pygpt_net/ui/layout/chat/output.py +27 -45
- pygpt_net/ui/layout/ctx/ctx_list.py +13 -4
- pygpt_net/ui/layout/toolbox/footer.py +18 -2
- pygpt_net/ui/main.py +2 -2
- pygpt_net/ui/menu/audio.py +12 -1
- pygpt_net/ui/menu/config.py +7 -11
- pygpt_net/ui/menu/debug.py +11 -1
- pygpt_net/ui/menu/theme.py +9 -2
- pygpt_net/ui/widget/filesystem/explorer.py +2 -2
- pygpt_net/ui/widget/lists/context.py +27 -5
- pygpt_net/ui/widget/tabs/Input.py +2 -2
- pygpt_net/ui/widget/tabs/body.py +2 -1
- pygpt_net/ui/widget/tabs/layout.py +195 -0
- pygpt_net/ui/widget/tabs/output.py +218 -55
- pygpt_net/ui/widget/textarea/html.py +11 -1
- pygpt_net/ui/widget/textarea/output.py +10 -1
- pygpt_net/ui/widget/textarea/search_input.py +4 -1
- pygpt_net/ui/widget/textarea/web.py +49 -9
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/METADATA +177 -183
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/RECORD +340 -325
- /pygpt_net/data/css/{web.dark.css → web-blocks.dark.css} +0 -0
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/LICENSE +0 -0
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/WHEEL +0 -0
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/entry_points.txt +0 -0
pygpt_net/core/tabs/tab.py
CHANGED
@@ -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: 2024.
|
9
|
+
# Updated Date: 2024.12.14 17:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from datetime import datetime
|
13
|
+
from typing import Dict, Any
|
13
14
|
|
14
15
|
|
15
16
|
class Tab:
|
@@ -21,6 +22,7 @@ class Tab:
|
|
21
22
|
TAB_FILES = 2
|
22
23
|
TAB_TOOL_PAINTER = 3
|
23
24
|
TAB_TOOL_CALENDAR = 4
|
25
|
+
TAB_TOOL = 100
|
24
26
|
|
25
27
|
def __init__(self):
|
26
28
|
"""
|
@@ -34,15 +36,23 @@ class Tab:
|
|
34
36
|
self.icon = None
|
35
37
|
self.tooltip = None
|
36
38
|
self.data_id = None
|
37
|
-
self.reference = None
|
38
39
|
self.new_idx = None
|
39
40
|
self.custom_name = False
|
41
|
+
self.child = None
|
42
|
+
self.parent = None
|
43
|
+
self.column_idx = 0
|
44
|
+
self.tool_id = None
|
40
45
|
|
41
46
|
dt = datetime.now()
|
42
47
|
self.created_at = dt
|
43
48
|
self.updated_at = dt
|
44
49
|
|
45
|
-
def to_dict(self):
|
50
|
+
def to_dict(self) -> Dict[str, Any]:
|
51
|
+
"""
|
52
|
+
Convert to dict
|
53
|
+
|
54
|
+
:return: dict
|
55
|
+
"""
|
46
56
|
return {
|
47
57
|
"uuid": str(self.uuid),
|
48
58
|
"pid": self.pid,
|
@@ -52,9 +62,20 @@ class Tab:
|
|
52
62
|
"icon": self.icon,
|
53
63
|
"tooltip": self.tooltip,
|
54
64
|
"data_id": self.data_id,
|
55
|
-
"
|
65
|
+
"child": str(self.child), # child widget
|
66
|
+
"parent": str(self.parent), # parent column
|
56
67
|
"custom_name": self.custom_name,
|
57
68
|
"custom_idx": self.new_idx,
|
58
69
|
"created_at": str(self.created_at),
|
59
70
|
"updated_at": str(self.updated_at),
|
60
|
-
|
71
|
+
"column_idx": self.column_idx,
|
72
|
+
"tool_id": self.tool_id,
|
73
|
+
}
|
74
|
+
|
75
|
+
def __str__(self) -> str:
|
76
|
+
"""
|
77
|
+
String representation
|
78
|
+
|
79
|
+
:return: str
|
80
|
+
"""
|
81
|
+
return str(self.to_dict())
|
pygpt_net/core/tokens.py
CHANGED
@@ -6,11 +6,16 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2024.
|
9
|
+
# Updated Date: 2024.12.14 22:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
|
+
from typing import Tuple, List
|
13
|
+
|
12
14
|
import tiktoken
|
13
15
|
|
16
|
+
from langchain_core.messages import ChatMessage as ChatMessageLangchain
|
17
|
+
from llama_index.core.base.llms.types import ChatMessage as ChatMessageLlama
|
18
|
+
|
14
19
|
from pygpt_net.core.types import (
|
15
20
|
MODE_AGENT,
|
16
21
|
MODE_AGENT_LLAMA,
|
@@ -37,7 +42,6 @@ CHAT_MODES = [
|
|
37
42
|
MODE_AUDIO,
|
38
43
|
]
|
39
44
|
|
40
|
-
|
41
45
|
class Tokens:
|
42
46
|
def __init__(self, window=None):
|
43
47
|
"""
|
@@ -48,7 +52,10 @@ class Tokens:
|
|
48
52
|
self.window = window
|
49
53
|
|
50
54
|
@staticmethod
|
51
|
-
def from_str(
|
55
|
+
def from_str(
|
56
|
+
string: str,
|
57
|
+
model: str = "gpt-4"
|
58
|
+
) -> int:
|
52
59
|
"""
|
53
60
|
Return number of tokens from string
|
54
61
|
|
@@ -91,7 +98,11 @@ class Tokens:
|
|
91
98
|
return 3
|
92
99
|
|
93
100
|
@staticmethod
|
94
|
-
def from_prompt(
|
101
|
+
def from_prompt(
|
102
|
+
text: str,
|
103
|
+
name: str,
|
104
|
+
model: str = "gpt-4"
|
105
|
+
) -> int:
|
95
106
|
"""
|
96
107
|
Return number of tokens from prompt
|
97
108
|
|
@@ -116,7 +127,10 @@ class Tokens:
|
|
116
127
|
return num
|
117
128
|
|
118
129
|
@staticmethod
|
119
|
-
def from_text(
|
130
|
+
def from_text(
|
131
|
+
text: str,
|
132
|
+
model: str = "gpt-4"
|
133
|
+
) -> int:
|
120
134
|
"""
|
121
135
|
Return number of tokens from text, without any extra tokens
|
122
136
|
|
@@ -138,7 +152,10 @@ class Tokens:
|
|
138
152
|
return num
|
139
153
|
|
140
154
|
@staticmethod
|
141
|
-
def from_messages(
|
155
|
+
def from_messages(
|
156
|
+
messages: List[dict],
|
157
|
+
model: str = "gpt-4"
|
158
|
+
) -> int:
|
142
159
|
"""
|
143
160
|
Return number of tokens from messages list
|
144
161
|
|
@@ -166,7 +183,10 @@ class Tokens:
|
|
166
183
|
return num
|
167
184
|
|
168
185
|
@staticmethod
|
169
|
-
def from_langchain_messages(
|
186
|
+
def from_langchain_messages(
|
187
|
+
messages: List[ChatMessageLangchain],
|
188
|
+
model: str = "gpt-4"
|
189
|
+
) -> int:
|
170
190
|
"""
|
171
191
|
Return number of tokens from prompt
|
172
192
|
|
@@ -183,7 +203,11 @@ class Tokens:
|
|
183
203
|
return num
|
184
204
|
|
185
205
|
@staticmethod
|
186
|
-
def from_llama_messages(
|
206
|
+
def from_llama_messages(
|
207
|
+
query: str,
|
208
|
+
messages: List[ChatMessageLlama],
|
209
|
+
model: str = "gpt-4"
|
210
|
+
) -> int:
|
187
211
|
"""
|
188
212
|
Return number of tokens from prompt
|
189
213
|
|
@@ -202,7 +226,11 @@ class Tokens:
|
|
202
226
|
return num
|
203
227
|
|
204
228
|
@staticmethod
|
205
|
-
def from_ctx(
|
229
|
+
def from_ctx(
|
230
|
+
ctx: CtxItem,
|
231
|
+
mode: str = MODE_CHAT,
|
232
|
+
model: str = "gpt-4"
|
233
|
+
) -> int:
|
206
234
|
"""
|
207
235
|
Return number of tokens from context ctx
|
208
236
|
|
@@ -280,7 +308,10 @@ class Tokens:
|
|
280
308
|
|
281
309
|
return num
|
282
310
|
|
283
|
-
def get_current(
|
311
|
+
def get_current(
|
312
|
+
self,
|
313
|
+
input_prompt: str
|
314
|
+
) -> Tuple[int, int, int, int, int, int, int, int, int]:
|
284
315
|
"""
|
285
316
|
Return current number of used tokens
|
286
317
|
|
@@ -364,7 +395,11 @@ class Tokens:
|
|
364
395
|
return input_tokens, system_tokens, extra_tokens, ctx_tokens, ctx_len, ctx_len_all, \
|
365
396
|
sum_tokens, max_current, threshold
|
366
397
|
|
367
|
-
def from_user(
|
398
|
+
def from_user(
|
399
|
+
self,
|
400
|
+
system_prompt: str,
|
401
|
+
input_prompt: str
|
402
|
+
) -> int:
|
368
403
|
"""
|
369
404
|
Count per-user used tokens
|
370
405
|
|
@@ -390,7 +425,7 @@ class Tokens:
|
|
390
425
|
return tokens
|
391
426
|
|
392
427
|
@staticmethod
|
393
|
-
def get_config(model: str) ->
|
428
|
+
def get_config(model: str) -> Tuple[str, int, int]:
|
394
429
|
"""
|
395
430
|
Return tokens config values
|
396
431
|
|
@@ -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: 2024.
|
9
|
+
# Updated Date: 2024.12.14 08:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import copy
|
@@ -15,6 +15,7 @@ import shutil
|
|
15
15
|
import json
|
16
16
|
import ssl
|
17
17
|
import time
|
18
|
+
from typing import Tuple
|
18
19
|
|
19
20
|
from urllib.request import urlopen, Request
|
20
21
|
|
@@ -134,7 +135,11 @@ class Updater:
|
|
134
135
|
if self.window.core.notepad.patch(version):
|
135
136
|
print("Migrated notepad. [OK]")
|
136
137
|
|
137
|
-
def patch_dir(
|
138
|
+
def patch_dir(
|
139
|
+
self,
|
140
|
+
dir_name: str = "",
|
141
|
+
force: bool = False
|
142
|
+
):
|
138
143
|
"""
|
139
144
|
Patch directory (replace all files)
|
140
145
|
|
@@ -154,7 +159,11 @@ class Updater:
|
|
154
159
|
except Exception as e:
|
155
160
|
self.window.core.debug.log(e)
|
156
161
|
|
157
|
-
def patch_file(
|
162
|
+
def patch_file(
|
163
|
+
self,
|
164
|
+
filename: str = "",
|
165
|
+
force: bool = False
|
166
|
+
):
|
158
167
|
"""
|
159
168
|
Patch file
|
160
169
|
|
@@ -175,7 +184,11 @@ class Updater:
|
|
175
184
|
except Exception as e:
|
176
185
|
self.window.core.debug.log(e)
|
177
186
|
|
178
|
-
def patch_css(
|
187
|
+
def patch_css(
|
188
|
+
self,
|
189
|
+
filename: str = "",
|
190
|
+
force: bool = False
|
191
|
+
):
|
179
192
|
"""
|
180
193
|
Patch css file
|
181
194
|
|
@@ -212,7 +225,7 @@ class Updater:
|
|
212
225
|
"""
|
213
226
|
return self.window.meta['website'] + "/api/version?v=" + str(self.window.meta['version'])
|
214
227
|
|
215
|
-
def get_thanks(self) ->
|
228
|
+
def get_thanks(self) -> Tuple[str, str, str]:
|
216
229
|
"""
|
217
230
|
Get contributors, donates and sponsors
|
218
231
|
|
@@ -237,7 +250,7 @@ class Updater:
|
|
237
250
|
|
238
251
|
return self.thanks
|
239
252
|
|
240
|
-
def get_fetch_thanks(self) ->
|
253
|
+
def get_fetch_thanks(self) -> Tuple[str, str, str]:
|
241
254
|
"""
|
242
255
|
Get contributors, donates and sponsors
|
243
256
|
|
@@ -247,7 +260,7 @@ class Updater:
|
|
247
260
|
return self.get_thanks()
|
248
261
|
return self.thanks
|
249
262
|
|
250
|
-
def check_silent(self) ->
|
263
|
+
def check_silent(self) -> Tuple[bool, str, str, str, str, str]:
|
251
264
|
"""
|
252
265
|
Check version in background
|
253
266
|
|
@@ -6,8 +6,9 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2024.
|
9
|
+
# Updated Date: 2024.12.14 00:00:00 #
|
10
10
|
# ================================================== #
|
11
|
+
|
11
12
|
import os
|
12
13
|
|
13
14
|
from pygpt_net.core.bridge.context import BridgeContext
|
@@ -24,7 +25,12 @@ class Analyzer:
|
|
24
25
|
"""
|
25
26
|
self.window = window
|
26
27
|
|
27
|
-
def send(
|
28
|
+
def send(
|
29
|
+
self,
|
30
|
+
ctx: CtxItem,
|
31
|
+
prompt: str,
|
32
|
+
files: dict
|
33
|
+
) -> str:
|
28
34
|
"""
|
29
35
|
Send text from user input (called from UI)
|
30
36
|
|
@@ -56,7 +62,11 @@ class Analyzer:
|
|
56
62
|
self.window.controller.attachment.unlock()
|
57
63
|
return output
|
58
64
|
|
59
|
-
def from_screenshot(
|
65
|
+
def from_screenshot(
|
66
|
+
self,
|
67
|
+
ctx: CtxItem,
|
68
|
+
prompt: str
|
69
|
+
) -> str:
|
60
70
|
"""
|
61
71
|
Image analysis from screenshot
|
62
72
|
|
@@ -75,7 +85,11 @@ class Analyzer:
|
|
75
85
|
}
|
76
86
|
return self.send(ctx, prompt, files)
|
77
87
|
|
78
|
-
def from_camera(
|
88
|
+
def from_camera(
|
89
|
+
self,
|
90
|
+
ctx: CtxItem,
|
91
|
+
prompt: str
|
92
|
+
) -> str:
|
79
93
|
"""
|
80
94
|
Image analysis from camera
|
81
95
|
|
@@ -94,7 +108,12 @@ class Analyzer:
|
|
94
108
|
else:
|
95
109
|
return "FAILED: There was a problem with capturing the image."
|
96
110
|
|
97
|
-
def from_path(
|
111
|
+
def from_path(
|
112
|
+
self,
|
113
|
+
ctx: CtxItem,
|
114
|
+
prompt: str,
|
115
|
+
path: str
|
116
|
+
) -> str:
|
98
117
|
"""
|
99
118
|
Image analysis from path
|
100
119
|
|
@@ -116,7 +135,11 @@ class Analyzer:
|
|
116
135
|
}
|
117
136
|
return self.send(ctx, prompt, files)
|
118
137
|
|
119
|
-
def from_current_attachments(
|
138
|
+
def from_current_attachments(
|
139
|
+
self,
|
140
|
+
ctx: CtxItem,
|
141
|
+
prompt: str
|
142
|
+
) -> str:
|
120
143
|
"""
|
121
144
|
Image analysis from current attachments
|
122
145
|
|
@@ -6,25 +6,37 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2024.
|
9
|
+
# Updated Date: 2024.12.14 19:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
|
+
from typing import Optional, List, Dict
|
13
|
+
|
12
14
|
from pygpt_net.provider.web.base import BaseProvider
|
13
15
|
|
16
|
+
from .helpers import Helpers
|
17
|
+
|
14
18
|
|
15
19
|
class Web:
|
20
|
+
|
21
|
+
PROVIDER_SEARCH_ENGINE = "search_engine"
|
22
|
+
|
16
23
|
def __init__(self, window=None):
|
17
24
|
"""
|
18
|
-
Web
|
25
|
+
Web core
|
19
26
|
|
20
27
|
:param window: Window instance
|
21
28
|
"""
|
22
29
|
self.window = window
|
30
|
+
self.helpers = Helpers(window)
|
23
31
|
self.providers = {
|
24
|
-
|
32
|
+
self.PROVIDER_SEARCH_ENGINE: {},
|
25
33
|
}
|
26
34
|
|
27
|
-
def is_registered(
|
35
|
+
def is_registered(
|
36
|
+
self,
|
37
|
+
id: str,
|
38
|
+
type: str = PROVIDER_SEARCH_ENGINE
|
39
|
+
) -> bool:
|
28
40
|
"""
|
29
41
|
Check if provider is registered
|
30
42
|
|
@@ -36,7 +48,10 @@ class Web:
|
|
36
48
|
return id in self.providers[type]
|
37
49
|
return False
|
38
50
|
|
39
|
-
def get_providers(
|
51
|
+
def get_providers(
|
52
|
+
self,
|
53
|
+
type: str = PROVIDER_SEARCH_ENGINE
|
54
|
+
) -> Dict[str, BaseProvider]:
|
40
55
|
"""
|
41
56
|
Get all providers
|
42
57
|
|
@@ -47,7 +62,10 @@ class Web:
|
|
47
62
|
return self.providers[type]
|
48
63
|
return {}
|
49
64
|
|
50
|
-
def get_ids(
|
65
|
+
def get_ids(
|
66
|
+
self,
|
67
|
+
type: str = PROVIDER_SEARCH_ENGINE
|
68
|
+
) -> List[str]:
|
51
69
|
"""
|
52
70
|
Get all providers ids
|
53
71
|
|
@@ -58,7 +76,11 @@ class Web:
|
|
58
76
|
return list(self.providers[type].keys())
|
59
77
|
return []
|
60
78
|
|
61
|
-
def get(
|
79
|
+
def get(
|
80
|
+
self,
|
81
|
+
id: str,
|
82
|
+
type: str = PROVIDER_SEARCH_ENGINE
|
83
|
+
) -> Optional[BaseProvider]:
|
62
84
|
"""
|
63
85
|
Get provider instance
|
64
86
|
|
@@ -0,0 +1,237 @@
|
|
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: 2024.12.15 01:00:00 #
|
10
|
+
# ================================================== #
|
11
|
+
|
12
|
+
import os
|
13
|
+
import uuid
|
14
|
+
from typing import Optional, List, Dict, Tuple, Union
|
15
|
+
|
16
|
+
import requests
|
17
|
+
|
18
|
+
from bs4 import BeautifulSoup
|
19
|
+
from urllib.parse import urljoin
|
20
|
+
|
21
|
+
|
22
|
+
class Helpers:
|
23
|
+
def __init__(self, window=None):
|
24
|
+
"""
|
25
|
+
Web helpers core
|
26
|
+
|
27
|
+
:param window: Window instance
|
28
|
+
"""
|
29
|
+
self.window = window
|
30
|
+
|
31
|
+
def request(
|
32
|
+
self,
|
33
|
+
url: str = "",
|
34
|
+
method: str = "GET",
|
35
|
+
headers: Optional[dict] = None,
|
36
|
+
params: Optional[dict] = None,
|
37
|
+
data: Optional[Union[str, dict]] = None,
|
38
|
+
json: Optional[dict] = None,
|
39
|
+
files: Optional[dict] = None,
|
40
|
+
cookies: Optional[dict] = None,
|
41
|
+
timeout: int = 10,
|
42
|
+
disable_ssl_verify: bool = False,
|
43
|
+
allow_redirects: bool = True,
|
44
|
+
stream: bool = False,
|
45
|
+
user_agent: Optional[str] = None,
|
46
|
+
) -> Tuple[Optional[int], Optional[str]]:
|
47
|
+
"""
|
48
|
+
Make HTTP request
|
49
|
+
|
50
|
+
:param url: URL
|
51
|
+
:param method: HTTP method
|
52
|
+
:param headers: Headers
|
53
|
+
:param params: GET parameters
|
54
|
+
:param data: POST data
|
55
|
+
:param json: JSON data
|
56
|
+
:param files: Files
|
57
|
+
:param cookies: Cookies
|
58
|
+
:param timeout: Timeout
|
59
|
+
:param disable_ssl_verify: Disable SSL verification
|
60
|
+
:param allow_redirects: Allow redirects
|
61
|
+
:param stream: Stream
|
62
|
+
:param user_agent: User agent
|
63
|
+
:return: status code, response text
|
64
|
+
"""
|
65
|
+
upload = {}
|
66
|
+
try:
|
67
|
+
method = method.upper()
|
68
|
+
session = requests.Session()
|
69
|
+
args = {}
|
70
|
+
|
71
|
+
if data:
|
72
|
+
args['data'] = data
|
73
|
+
if json:
|
74
|
+
args['json'] = json
|
75
|
+
if cookies:
|
76
|
+
args['cookies'] = cookies
|
77
|
+
if params:
|
78
|
+
args['params'] = params
|
79
|
+
if headers:
|
80
|
+
args['headers'] = headers
|
81
|
+
|
82
|
+
args['timeout'] = timeout
|
83
|
+
if disable_ssl_verify:
|
84
|
+
args['verify'] = False
|
85
|
+
if not allow_redirects:
|
86
|
+
args['allow_redirects'] = False
|
87
|
+
if stream:
|
88
|
+
args['stream'] = True
|
89
|
+
if user_agent:
|
90
|
+
if 'headers' not in args:
|
91
|
+
args['headers'] = {}
|
92
|
+
args['headers']['User-Agent'] = user_agent
|
93
|
+
|
94
|
+
if files:
|
95
|
+
for key, value in files.items():
|
96
|
+
if os.path.exists(value) and os.path.isfile(value):
|
97
|
+
upload[key] = open(value, 'rb')
|
98
|
+
args['files'] = upload
|
99
|
+
|
100
|
+
if method == 'GET':
|
101
|
+
response = session.get(url, **args)
|
102
|
+
elif method == 'POST':
|
103
|
+
response = session.post(url, **args)
|
104
|
+
elif method == 'PUT':
|
105
|
+
response = session.put(url, **args)
|
106
|
+
elif method == 'DELETE':
|
107
|
+
response = session.delete(url, **args)
|
108
|
+
elif method == 'PATCH':
|
109
|
+
response = session.patch(url, **args)
|
110
|
+
else:
|
111
|
+
return None, f'Invalid HTTP method: {method}'
|
112
|
+
for k in upload:
|
113
|
+
upload[k].close() # close files if opened
|
114
|
+
return response.status_code, response.text
|
115
|
+
except Exception as e:
|
116
|
+
for k in upload:
|
117
|
+
upload[k].close() # close files if opened
|
118
|
+
return None, f'Error: {e}'
|
119
|
+
|
120
|
+
def get_main_image(self, url: str) -> Optional[str]:
|
121
|
+
"""
|
122
|
+
Get main image from URL
|
123
|
+
|
124
|
+
:param url: URL to get image from
|
125
|
+
:return: image URL
|
126
|
+
"""
|
127
|
+
response = requests.get(url)
|
128
|
+
soup = BeautifulSoup(response.content, 'html.parser')
|
129
|
+
|
130
|
+
og_image = soup.find('meta', property='og:image')
|
131
|
+
if og_image and og_image.get('content'):
|
132
|
+
return og_image['content']
|
133
|
+
|
134
|
+
twitter_image = soup.find('meta', attrs={'name': 'twitter:image'})
|
135
|
+
if twitter_image and twitter_image.get('content'):
|
136
|
+
return twitter_image['content']
|
137
|
+
|
138
|
+
link_image = soup.find('link', rel='image_src')
|
139
|
+
if link_image and link_image.get('href'):
|
140
|
+
return link_image['href']
|
141
|
+
|
142
|
+
images = soup.find_all('img')
|
143
|
+
if images:
|
144
|
+
images = [img for img in images if 'logo' not in (img.get('src') or '').lower()]
|
145
|
+
largest_image = None
|
146
|
+
max_area = 0
|
147
|
+
for img in images:
|
148
|
+
src = img.get('src')
|
149
|
+
if not src:
|
150
|
+
continue
|
151
|
+
src = requests.compat.urljoin(url, src)
|
152
|
+
try:
|
153
|
+
img_response = requests.get(src, stream=True, timeout=5)
|
154
|
+
img_response.raw.decode_content = True
|
155
|
+
|
156
|
+
from PIL import Image
|
157
|
+
image = Image.open(img_response.raw)
|
158
|
+
width, height = image.size
|
159
|
+
area = width * height
|
160
|
+
if area > max_area:
|
161
|
+
max_area = area
|
162
|
+
largest_image = src
|
163
|
+
except:
|
164
|
+
continue
|
165
|
+
if largest_image:
|
166
|
+
return largest_image
|
167
|
+
return None
|
168
|
+
|
169
|
+
def get_links(self, url: str) -> List[Dict[str, str]]:
|
170
|
+
"""
|
171
|
+
Get links from URL
|
172
|
+
|
173
|
+
:param url: URL to get links from
|
174
|
+
:return: links list
|
175
|
+
"""
|
176
|
+
response = requests.get(url)
|
177
|
+
soup = BeautifulSoup(response.content, 'html.parser')
|
178
|
+
links = []
|
179
|
+
urls = []
|
180
|
+
for link in soup.find_all('a'):
|
181
|
+
try:
|
182
|
+
name = link.get_text(strip=True)
|
183
|
+
address = link.get('href')
|
184
|
+
if address:
|
185
|
+
address = urljoin(url, address)
|
186
|
+
if not name:
|
187
|
+
title = link.get('title')
|
188
|
+
if title:
|
189
|
+
name = title
|
190
|
+
else:
|
191
|
+
name = address
|
192
|
+
if address not in urls:
|
193
|
+
urls.append(address)
|
194
|
+
links.append({name: address})
|
195
|
+
except:
|
196
|
+
continue
|
197
|
+
return links
|
198
|
+
|
199
|
+
|
200
|
+
def get_images(self, url: str) -> List[str]:
|
201
|
+
"""
|
202
|
+
Get images from URL
|
203
|
+
|
204
|
+
:param url: URL to get images from
|
205
|
+
:return: images list
|
206
|
+
"""
|
207
|
+
response = requests.get(url)
|
208
|
+
soup = BeautifulSoup(response.content, 'html.parser')
|
209
|
+
images = []
|
210
|
+
for img in soup.find_all('img'):
|
211
|
+
try:
|
212
|
+
address = img.get('src')
|
213
|
+
if address:
|
214
|
+
address = urljoin(url, address)
|
215
|
+
if address not in images:
|
216
|
+
images.append(address)
|
217
|
+
except:
|
218
|
+
continue
|
219
|
+
return images
|
220
|
+
|
221
|
+
def download_image(self, img: str) -> str:
|
222
|
+
"""
|
223
|
+
Download image from URL
|
224
|
+
|
225
|
+
:param img: URL to download image from
|
226
|
+
:return: local path to image
|
227
|
+
"""
|
228
|
+
dir = self.window.core.config.get_user_dir("img")
|
229
|
+
response = requests.get(img, stream=True)
|
230
|
+
name = img.replace("http://", "").replace("https://", "").replace("/", "_")
|
231
|
+
path = os.path.join(dir, name)
|
232
|
+
if os.path.exists(path):
|
233
|
+
name = name + uuid.uuid4().hex[:6].upper()
|
234
|
+
download_path = os.path.join(dir, name)
|
235
|
+
with open(download_path, 'wb', ) as f:
|
236
|
+
f.write(response.content)
|
237
|
+
return self.window.core.filesystem.make_local(download_path)
|