pygpt-net 2.4.37__py3-none-any.whl → 2.4.41__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 +29 -0
- README.md +44 -115
- pygpt_net/CHANGELOG.txt +29 -0
- pygpt_net/__init__.py +3 -3
- 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 +25 -4
- pygpt_net/controller/calendar/__init__.py +23 -4
- pygpt_net/controller/calendar/note.py +57 -11
- pygpt_net/controller/camera.py +3 -2
- pygpt_net/controller/chat/__init__.py +5 -3
- pygpt_net/controller/chat/attachment.py +34 -7
- 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 +52 -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/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 +71 -3
- pygpt_net/core/audio/context.py +7 -2
- pygpt_net/core/bridge/__init__.py +22 -6
- pygpt_net/core/bridge/context.py +5 -3
- 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/tabs.py +5 -2
- 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/idx/__init__.py +34 -25
- pygpt_net/core/idx/chat.py +40 -16
- pygpt_net/core/idx/context.py +6 -2
- pygpt_net/core/idx/indexing.py +84 -35
- 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/llm/__init__.py +13 -3
- pygpt_net/core/locale.py +34 -8
- pygpt_net/core/models.py +4 -3
- pygpt_net/core/notepad.py +9 -4
- pygpt_net/core/plugins.py +7 -6
- pygpt_net/core/presets.py +19 -10
- pygpt_net/core/profile.py +12 -6
- 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/renderer.py +313 -63
- pygpt_net/core/settings.py +9 -4
- pygpt_net/core/tabs/__init__.py +290 -103
- pygpt_net/core/tabs/tab.py +17 -4
- pygpt_net/core/tokens.py +44 -11
- pygpt_net/core/updater/__init__.py +20 -7
- pygpt_net/core/vision/analyzer.py +29 -6
- pygpt_net/core/web.py +130 -2
- 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 +17 -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 +20 -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/icons.qrc +1 -0
- pygpt_net/icons_rc.py +165 -136
- pygpt_net/item/ctx.py +46 -24
- pygpt_net/plugin/audio_input/simple.py +21 -5
- pygpt_net/plugin/audio_output/__init__.py +4 -1
- pygpt_net/plugin/base/config.py +4 -2
- pygpt_net/plugin/base/plugin.py +26 -6
- pygpt_net/plugin/base/worker.py +37 -9
- pygpt_net/plugin/cmd_code_interpreter/__init__.py +39 -37
- pygpt_net/plugin/cmd_code_interpreter/runner.py +25 -12
- pygpt_net/plugin/cmd_web/__init__.py +46 -6
- pygpt_net/plugin/cmd_web/config.py +74 -48
- pygpt_net/plugin/cmd_web/websearch.py +61 -28
- pygpt_net/plugin/cmd_web/worker.py +79 -13
- pygpt_net/provider/core/config/patch.py +43 -1
- pygpt_net/provider/core/ctx/base.py +4 -1
- pygpt_net/provider/core/ctx/db_sqlite/__init__.py +10 -1
- pygpt_net/provider/core/ctx/db_sqlite/storage.py +22 -1
- pygpt_net/provider/gpt/assistants.py +10 -9
- pygpt_net/provider/gpt/audio.py +3 -2
- pygpt_net/provider/gpt/chat.py +8 -7
- pygpt_net/provider/gpt/completion.py +6 -4
- pygpt_net/provider/gpt/image.py +9 -2
- pygpt_net/provider/gpt/store.py +14 -13
- pygpt_net/provider/gpt/vision.py +6 -5
- pygpt_net/tools/__init__.py +9 -1
- pygpt_net/tools/base.py +15 -1
- pygpt_net/tools/code_interpreter/__init__.py +174 -75
- 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 +78 -23
- pygpt_net/tools/html_canvas/ui/dialogs.py +46 -62
- pygpt_net/tools/html_canvas/ui/widgets.py +96 -3
- 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 +26 -44
- 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/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.41.dist-info}/METADATA +45 -116
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.41.dist-info}/RECORD +255 -247
- /pygpt_net/data/css/{web.dark.css → web-blocks.dark.css} +0 -0
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.41.dist-info}/LICENSE +0 -0
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.41.dist-info}/WHEEL +0 -0
- {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.41.dist-info}/entry_points.txt +0 -0
@@ -6,7 +6,7 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2024.
|
9
|
+
# Updated Date: 2024.12.13 08:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from pygpt_net.plugin.base.config import BaseConfig, BasePlugin
|
@@ -41,6 +41,15 @@ class Config(BaseConfig):
|
|
41
41
|
min=1,
|
42
42
|
max=None,
|
43
43
|
)
|
44
|
+
plugin.add_option(
|
45
|
+
"max_open_urls",
|
46
|
+
type="int",
|
47
|
+
value=1,
|
48
|
+
label="Number of max URLs to open at once",
|
49
|
+
description="Number of max URLs to open at once",
|
50
|
+
min=1,
|
51
|
+
max=None,
|
52
|
+
)
|
44
53
|
plugin.add_option(
|
45
54
|
"max_page_content_length",
|
46
55
|
type="int",
|
@@ -59,6 +68,14 @@ class Config(BaseConfig):
|
|
59
68
|
min=1,
|
60
69
|
max=None,
|
61
70
|
)
|
71
|
+
plugin.add_option(
|
72
|
+
"raw",
|
73
|
+
type="bool",
|
74
|
+
value=True,
|
75
|
+
label="Use raw content (without summarization)",
|
76
|
+
description="Return raw content from web search instead of summarized content",
|
77
|
+
tooltip="Use raw content for search",
|
78
|
+
)
|
62
79
|
plugin.add_option(
|
63
80
|
"disable_ssl",
|
64
81
|
type="bool",
|
@@ -67,6 +84,14 @@ class Config(BaseConfig):
|
|
67
84
|
description="Disables SSL verification when crawling web pages",
|
68
85
|
tooltip="Disable SSL verify",
|
69
86
|
)
|
87
|
+
plugin.add_option(
|
88
|
+
"img_thumbnail",
|
89
|
+
type="bool",
|
90
|
+
value=True,
|
91
|
+
label="Show thumbnail images",
|
92
|
+
description="Enable fetching thumbnails from opened websites",
|
93
|
+
tooltip="Enable fetching thumbnails from opened websites",
|
94
|
+
)
|
70
95
|
plugin.add_option(
|
71
96
|
"timeout",
|
72
97
|
type="int",
|
@@ -86,7 +111,7 @@ class Config(BaseConfig):
|
|
86
111
|
plugin.add_option(
|
87
112
|
"max_result_length",
|
88
113
|
type="int",
|
89
|
-
value=
|
114
|
+
value=50000,
|
90
115
|
label="Max result length",
|
91
116
|
description="Max length of summarized result (characters)",
|
92
117
|
min=0,
|
@@ -104,10 +129,10 @@ class Config(BaseConfig):
|
|
104
129
|
plugin.add_option(
|
105
130
|
"model_tmp_query",
|
106
131
|
type="combo",
|
107
|
-
value="gpt-
|
132
|
+
value="gpt-4o-mini",
|
108
133
|
label="Model for query in-memory index",
|
109
134
|
description="Model used for query in-memory index for `web_index_query` command, "
|
110
|
-
"default: gpt-
|
135
|
+
"default: gpt-4o-mini",
|
111
136
|
tooltip="Query model",
|
112
137
|
use="models",
|
113
138
|
tab="indexing",
|
@@ -134,10 +159,11 @@ class Config(BaseConfig):
|
|
134
159
|
)
|
135
160
|
plugin.add_option(
|
136
161
|
"summary_model",
|
137
|
-
type="
|
138
|
-
value="gpt-
|
162
|
+
type="combo",
|
163
|
+
value="gpt-4o-mini",
|
139
164
|
label="Model used for web page summarize",
|
140
165
|
description="Model used for web page summarize, default: gpt-3.5-turbo-1106",
|
166
|
+
use="models",
|
141
167
|
advanced=True,
|
142
168
|
)
|
143
169
|
plugin.add_option(
|
@@ -163,39 +189,9 @@ class Config(BaseConfig):
|
|
163
189
|
)
|
164
190
|
|
165
191
|
# commands
|
166
|
-
plugin.add_cmd(
|
167
|
-
"web_search",
|
168
|
-
instruction="search the Web for more info, prepare a query for the search engine itself, start from page 1. "
|
169
|
-
"If no results, then try the next page. "
|
170
|
-
"Use a custom summary prompt if necessary, otherwise, a default summary will be used. "
|
171
|
-
"Max pages: {max_pages}",
|
172
|
-
params=[
|
173
|
-
{
|
174
|
-
"name": "query",
|
175
|
-
"type": "str",
|
176
|
-
"description": "search query",
|
177
|
-
"required": True,
|
178
|
-
},
|
179
|
-
{
|
180
|
-
"name": "page",
|
181
|
-
"type": "int",
|
182
|
-
"description": "page number",
|
183
|
-
"required": False,
|
184
|
-
},
|
185
|
-
{
|
186
|
-
"name": "summarize_prompt",
|
187
|
-
"type": "str",
|
188
|
-
"description": "summary prompt",
|
189
|
-
"required": False,
|
190
|
-
},
|
191
|
-
],
|
192
|
-
enabled=True,
|
193
|
-
description="If enabled, model will be able to search the Web",
|
194
|
-
)
|
195
192
|
plugin.add_cmd(
|
196
193
|
"web_url_open",
|
197
|
-
instruction="read and get
|
198
|
-
"otherwise default summary will be used",
|
194
|
+
instruction="read and get text content from ANY website URL. Always open a max of {max_urls} URLs at a time.",
|
199
195
|
params=[
|
200
196
|
{
|
201
197
|
"name": "url",
|
@@ -203,19 +199,13 @@ class Config(BaseConfig):
|
|
203
199
|
"description": "URL to website",
|
204
200
|
"required": True,
|
205
201
|
},
|
206
|
-
{
|
207
|
-
"name": "summarize_prompt",
|
208
|
-
"type": "str",
|
209
|
-
"description": "summary prompt",
|
210
|
-
"required": False,
|
211
|
-
},
|
212
202
|
],
|
213
203
|
enabled=True,
|
214
|
-
description="If enabled, model will be able to open URL and
|
204
|
+
description="If enabled, model will be able to open URL and read text content from it",
|
215
205
|
)
|
216
206
|
plugin.add_cmd(
|
217
207
|
"web_url_raw",
|
218
|
-
instruction="read and get raw HTML
|
208
|
+
instruction="read and get raw HTML body from ANY website URL. Always open a max of {max_urls} URLs at a time.",
|
219
209
|
params=[
|
220
210
|
{
|
221
211
|
"name": "url",
|
@@ -225,12 +215,14 @@ class Config(BaseConfig):
|
|
225
215
|
},
|
226
216
|
],
|
227
217
|
enabled=True,
|
228
|
-
description="If enabled, model will be able to open specified URL and get raw
|
218
|
+
description="If enabled, model will be able to open specified URL and get raw HTML body from it",
|
229
219
|
)
|
230
220
|
plugin.add_cmd(
|
231
|
-
"
|
221
|
+
"web_search",
|
232
222
|
instruction="search the Web for list of URLs, prepare search query itself, list of "
|
233
|
-
"URLs will be returned, 10 links per page max."
|
223
|
+
"URLs will be returned, 10 links per page max. After receiving the list of URLs, "
|
224
|
+
"choose the best matched URLs and use the `web_url_open` command to read the content. "
|
225
|
+
"Always open a max of {max_urls} URLs at a time.",
|
234
226
|
params=[
|
235
227
|
{
|
236
228
|
"name": "query",
|
@@ -254,6 +246,40 @@ class Config(BaseConfig):
|
|
254
246
|
enabled=True,
|
255
247
|
description="If enabled, model will be able to search the Web and get founded URLs list",
|
256
248
|
)
|
249
|
+
plugin.add_cmd(
|
250
|
+
"web_extract_links",
|
251
|
+
instruction="open webpage and get list of all links from it",
|
252
|
+
params=[
|
253
|
+
{
|
254
|
+
"name": "url",
|
255
|
+
"type": "str",
|
256
|
+
"description": "URL to website",
|
257
|
+
"required": True,
|
258
|
+
},
|
259
|
+
],
|
260
|
+
enabled=True,
|
261
|
+
description="If enabled, model will be able to open URL and get list of all links from it",
|
262
|
+
)
|
263
|
+
plugin.add_cmd(
|
264
|
+
"web_extract_images",
|
265
|
+
instruction="open webpage and get list of all images from it",
|
266
|
+
params=[
|
267
|
+
{
|
268
|
+
"name": "url",
|
269
|
+
"type": "str",
|
270
|
+
"description": "URL to website",
|
271
|
+
"required": True,
|
272
|
+
},
|
273
|
+
{
|
274
|
+
"name": "download",
|
275
|
+
"type": "bool",
|
276
|
+
"description": "Download images to disk if user wants to, default: False",
|
277
|
+
"required": False,
|
278
|
+
},
|
279
|
+
],
|
280
|
+
enabled=True,
|
281
|
+
description="If enabled, model will be able to open URL and get list of all images from it",
|
282
|
+
)
|
257
283
|
plugin.add_cmd(
|
258
284
|
"web_index",
|
259
285
|
instruction="",
|
@@ -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.13 08:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import re
|
13
|
+
|
13
14
|
from bs4 import BeautifulSoup
|
14
15
|
|
15
16
|
from pygpt_net.core.events import KernelEvent
|
@@ -194,19 +195,22 @@ class WebSearch:
|
|
194
195
|
query: str,
|
195
196
|
page_no: int = 1,
|
196
197
|
summarize_prompt: str = ""
|
197
|
-
) -> (str, int, int, str):
|
198
|
+
) -> (str, int, int, str, str):
|
198
199
|
"""
|
199
200
|
Get result from search query
|
200
201
|
|
201
202
|
:param query: query to search
|
202
203
|
:param page_no: page number
|
203
204
|
:param summarize_prompt: custom prompt
|
204
|
-
:return: result, total_found, current, url
|
205
|
+
:return: result, total_found, current, url, thumb image
|
205
206
|
"""
|
206
207
|
self.log("Using web query: " + query)
|
207
208
|
urls = self.get_urls(query)
|
208
209
|
|
209
210
|
# get options
|
211
|
+
is_summary = True
|
212
|
+
if self.plugin.get_option_value("raw"):
|
213
|
+
is_summary = False
|
210
214
|
max_per_page = int(self.plugin.get_option_value("max_page_content_length"))
|
211
215
|
chunk_size = int(self.plugin.get_option_value("chunk_size"))
|
212
216
|
max_result_size = int(self.plugin.get_option_value("max_result_length"))
|
@@ -216,6 +220,7 @@ class WebSearch:
|
|
216
220
|
i = 1
|
217
221
|
current = 1
|
218
222
|
url = ""
|
223
|
+
img = None
|
219
224
|
for url in urls:
|
220
225
|
if url is None or url == "":
|
221
226
|
continue
|
@@ -236,19 +241,27 @@ class WebSearch:
|
|
236
241
|
if 0 < max_per_page < len(content):
|
237
242
|
content = content[:max_per_page]
|
238
243
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
244
|
+
# get summary
|
245
|
+
if is_summary:
|
246
|
+
chunks = self.to_chunks(content, chunk_size) # it returns list of chunks
|
247
|
+
self.debug(
|
248
|
+
"Plugin: cmd_web: URL: {}".format(url)
|
249
|
+
)
|
250
|
+
result = self.get_summary(
|
251
|
+
chunks,
|
252
|
+
str(query),
|
253
|
+
summarize_prompt,
|
254
|
+
)
|
255
|
+
else:
|
256
|
+
# no summary
|
257
|
+
result = str(content)
|
258
|
+
|
248
259
|
# if result then stop
|
249
260
|
if result is not None and result != "":
|
261
|
+
# get thumbnail image
|
262
|
+
if self.plugin.get_option_value("img_thumbnail"):
|
263
|
+
img = self.plugin.window.core.web.get_main_image(url)
|
250
264
|
self.log("Summary generated (chars: {})".format(len(result)))
|
251
|
-
|
252
265
|
# index webpage if auto-index is enabled
|
253
266
|
self.index_url(url)
|
254
267
|
break
|
@@ -262,7 +275,7 @@ class WebSearch:
|
|
262
275
|
"Plugin: cmd_web: summary length: {}".format(len(result))
|
263
276
|
)
|
264
277
|
|
265
|
-
if len(result)
|
278
|
+
if 0 < max_result_size < len(result):
|
266
279
|
result = result[:max_result_size]
|
267
280
|
|
268
281
|
self.debug(
|
@@ -273,25 +286,33 @@ class WebSearch:
|
|
273
286
|
result, \
|
274
287
|
total_found, \
|
275
288
|
current, \
|
276
|
-
url
|
289
|
+
url, \
|
290
|
+
img
|
277
291
|
|
278
|
-
def open_url(self, url: str, summarize_prompt: str = "") -> (str, str):
|
292
|
+
def open_url(self, url: str, summarize_prompt: str = "") -> (str, str, str):
|
279
293
|
"""
|
280
294
|
Get result from specified URL
|
281
295
|
|
282
296
|
:param url: URL to visit
|
283
297
|
:param summarize_prompt: custom prompt
|
284
|
-
:return: result, url
|
298
|
+
:return: result, url, thumb image
|
285
299
|
"""
|
286
300
|
self.log("Using URL: " + url)
|
287
|
-
|
288
301
|
# get options
|
302
|
+
is_summary = True
|
303
|
+
if self.plugin.get_option_value("raw"):
|
304
|
+
is_summary = False
|
289
305
|
max_per_page = int(self.plugin.get_option_value("max_page_content_length"))
|
290
306
|
chunk_size = int(self.plugin.get_option_value("chunk_size"))
|
291
307
|
max_result_size = int(self.plugin.get_option_value("max_result_length"))
|
292
308
|
|
309
|
+
img = None
|
293
310
|
self.log("URL: " + url)
|
294
311
|
content = self.query_url(url)
|
312
|
+
|
313
|
+
if content is None:
|
314
|
+
return None, url, img
|
315
|
+
|
295
316
|
self.log("Content found (chars: {}). Please wait...".format(len(content)))
|
296
317
|
|
297
318
|
# index webpage if auto-index is enabled
|
@@ -300,14 +321,23 @@ class WebSearch:
|
|
300
321
|
|
301
322
|
if 0 < max_per_page < len(content):
|
302
323
|
content = content[:max_per_page]
|
303
|
-
chunks = self.to_chunks(
|
304
|
-
content,
|
305
|
-
chunk_size,
|
306
|
-
) # it returns list of chunks
|
307
324
|
|
308
325
|
self.debug("Plugin: cmd_web: URL: {}".format(url)) # log
|
309
326
|
|
310
|
-
|
327
|
+
# get summary
|
328
|
+
if is_summary:
|
329
|
+
chunks = self.to_chunks(
|
330
|
+
content,
|
331
|
+
chunk_size,
|
332
|
+
) # it returns list of chunks
|
333
|
+
result = self.get_summary(chunks, "", summarize_prompt)
|
334
|
+
else:
|
335
|
+
# no summary
|
336
|
+
result = str(content)
|
337
|
+
|
338
|
+
# get thumbnail image
|
339
|
+
if self.plugin.get_option_value("img_thumbnail"):
|
340
|
+
img = self.plugin.window.core.web.get_main_image(url)
|
311
341
|
|
312
342
|
if result is not None and result != "":
|
313
343
|
self.log("Summary generated (chars: {})".format(len(result)))
|
@@ -318,21 +348,21 @@ class WebSearch:
|
|
318
348
|
"Plugin: cmd_web: summary length: {}".format(len(result))
|
319
349
|
)
|
320
350
|
|
321
|
-
if len(result)
|
351
|
+
if 0 < max_result_size < len(result):
|
322
352
|
result = result[:max_result_size]
|
323
353
|
|
324
354
|
self.debug(
|
325
355
|
"Plugin: cmd_web: result length: {}".format(len(result))
|
326
356
|
)
|
327
357
|
|
328
|
-
return result, url
|
358
|
+
return result, url, img
|
329
359
|
|
330
|
-
def open_url_raw(self, url: str) -> (str, str):
|
360
|
+
def open_url_raw(self, url: str) -> (str, str, str):
|
331
361
|
"""
|
332
362
|
Get raw content from specified URL
|
333
363
|
|
334
364
|
:param url: URL to visit
|
335
|
-
:return: result, url
|
365
|
+
:return: result, url, thumb image
|
336
366
|
"""
|
337
367
|
self.log("Using URL: " + url)
|
338
368
|
|
@@ -343,8 +373,11 @@ class WebSearch:
|
|
343
373
|
result = self.query_url(url)
|
344
374
|
self.log("Content found (chars: {}). Please wait...".format(len(result)))
|
345
375
|
|
376
|
+
img = None
|
346
377
|
# index webpage if auto-index is enabled
|
347
378
|
if result:
|
379
|
+
if self.plugin.get_option_value("img_thumbnail"):
|
380
|
+
img = self.plugin.window.core.web.get_main_image(url)
|
348
381
|
self.index_url(url)
|
349
382
|
|
350
383
|
# strip if too long
|
@@ -355,7 +388,7 @@ class WebSearch:
|
|
355
388
|
"Plugin: cmd_web: result length: {}".format(len(result))
|
356
389
|
)
|
357
390
|
|
358
|
-
return result, url
|
391
|
+
return result, url, img
|
359
392
|
|
360
393
|
def index_url(self, url: str):
|
361
394
|
"""
|
@@ -6,12 +6,13 @@
|
|
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.13 08:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import json
|
13
13
|
|
14
14
|
from PySide6.QtCore import Slot
|
15
|
+
|
15
16
|
from pygpt_net.plugin.base.worker import BaseWorker, BaseSignals
|
16
17
|
|
17
18
|
|
@@ -40,7 +41,7 @@ class Worker(BaseWorker):
|
|
40
41
|
response = None
|
41
42
|
try:
|
42
43
|
if item["cmd"] == "web_search":
|
43
|
-
response = self.
|
44
|
+
response = self.cmd_web_urls(item) # return URLs
|
44
45
|
|
45
46
|
elif item["cmd"] == "web_url_open":
|
46
47
|
response = self.cmd_web_url_open(item)
|
@@ -57,6 +58,12 @@ class Worker(BaseWorker):
|
|
57
58
|
elif item["cmd"] == "web_index_query":
|
58
59
|
response = self.cmd_web_index_query(item)
|
59
60
|
|
61
|
+
elif item["cmd"] == "web_extract_links":
|
62
|
+
response = self.cmd_web_extract_links(item)
|
63
|
+
|
64
|
+
elif item["cmd"] == "web_extract_images":
|
65
|
+
response = self.cmd_web_extract_images(item)
|
66
|
+
|
60
67
|
if response:
|
61
68
|
responses.append(response)
|
62
69
|
|
@@ -91,7 +98,7 @@ class Worker(BaseWorker):
|
|
91
98
|
prompt = self.get_param(item, "summarize_prompt")
|
92
99
|
|
93
100
|
query = self.get_param(item, "query", "")
|
94
|
-
content, total_found, current, url = self.websearch.make_query(
|
101
|
+
content, total_found, current, url, img = self.websearch.make_query(
|
95
102
|
query,
|
96
103
|
page,
|
97
104
|
prompt,
|
@@ -105,8 +112,12 @@ class Worker(BaseWorker):
|
|
105
112
|
'total_found': total_found,
|
106
113
|
}
|
107
114
|
if url:
|
108
|
-
self.ctx.
|
115
|
+
self.ctx.urls_before.append(url)
|
116
|
+
if img:
|
117
|
+
result["thumb_img"] = img
|
118
|
+
self.ctx.images_before.append(img)
|
109
119
|
|
120
|
+
self.ctx.save_reply = True # leave links in context
|
110
121
|
return self.make_response(item, result)
|
111
122
|
|
112
123
|
def cmd_web_url_open(self, item: dict) -> dict:
|
@@ -122,7 +133,7 @@ class Worker(BaseWorker):
|
|
122
133
|
url = self.get_param(item, "url", "")
|
123
134
|
|
124
135
|
self.msg = "Opening Web URL: '{}'".format(url)
|
125
|
-
content, url = self.websearch.open_url(
|
136
|
+
content, url, img = self.websearch.open_url(
|
126
137
|
url,
|
127
138
|
prompt,
|
128
139
|
)
|
@@ -130,9 +141,12 @@ class Worker(BaseWorker):
|
|
130
141
|
'url': url,
|
131
142
|
'content': content,
|
132
143
|
}
|
133
|
-
context = "From: " + url + ":\n--------------------------------\n" + content
|
144
|
+
context = "From: " + url + ":\n--------------------------------\n" + str(content)
|
134
145
|
if url:
|
135
|
-
self.ctx.
|
146
|
+
self.ctx.urls_before.append(url)
|
147
|
+
if img:
|
148
|
+
result["thumb_img"] = img
|
149
|
+
self.ctx.images_before.append(img)
|
136
150
|
|
137
151
|
extra = {
|
138
152
|
"context": context,
|
@@ -148,16 +162,19 @@ class Worker(BaseWorker):
|
|
148
162
|
"""
|
149
163
|
url = self.get_param(item, "url", "")
|
150
164
|
self.msg = "Opening Web URL: '{}'".format(url)
|
151
|
-
content, url = self.websearch.open_url_raw(
|
165
|
+
content, url, img = self.websearch.open_url_raw(
|
152
166
|
url,
|
153
167
|
)
|
154
168
|
result = {
|
155
169
|
'url': url,
|
156
170
|
'content': content,
|
157
171
|
}
|
158
|
-
context = "From: " + url + ":\n--------------------------------\n" + content
|
172
|
+
context = "From: " + url + ":\n--------------------------------\n" + str(content)
|
159
173
|
if url:
|
160
|
-
self.ctx.
|
174
|
+
self.ctx.urls_before.append(url)
|
175
|
+
if img:
|
176
|
+
result["thumb_img"] = img
|
177
|
+
self.ctx.images_before.append(img)
|
161
178
|
|
162
179
|
extra = {
|
163
180
|
"context": context,
|
@@ -201,7 +218,7 @@ class Worker(BaseWorker):
|
|
201
218
|
}
|
202
219
|
if urls:
|
203
220
|
for url in urls:
|
204
|
-
self.ctx.
|
221
|
+
self.ctx.urls_before.append(url)
|
205
222
|
|
206
223
|
return self.make_response(item, result)
|
207
224
|
|
@@ -247,7 +264,7 @@ class Worker(BaseWorker):
|
|
247
264
|
'errors': errors,
|
248
265
|
}
|
249
266
|
if url and (url.startswith("http://") or url.startswith("https://")):
|
250
|
-
self.ctx.
|
267
|
+
self.ctx.urls_before.append(url)
|
251
268
|
|
252
269
|
extra = {
|
253
270
|
"url": url,
|
@@ -327,9 +344,58 @@ class Worker(BaseWorker):
|
|
327
344
|
|
328
345
|
# add URL to context
|
329
346
|
if url and (url.startswith("http://") or url.startswith("https://")):
|
330
|
-
self.ctx.
|
347
|
+
self.ctx.urls_before.append(url)
|
331
348
|
|
332
349
|
extra = {
|
333
350
|
"context": context,
|
334
351
|
}
|
335
352
|
return self.make_response(item, result, extra=extra)
|
353
|
+
|
354
|
+
def cmd_web_extract_links(self, item: dict) -> dict:
|
355
|
+
"""
|
356
|
+
Web extract links command
|
357
|
+
|
358
|
+
:param item: command item
|
359
|
+
:return: response item
|
360
|
+
"""
|
361
|
+
url = ""
|
362
|
+
if self.has_param(item, "url"):
|
363
|
+
url = self.get_param(item, "url")
|
364
|
+
if not url:
|
365
|
+
return self.make_response(item, "No URL provided")
|
366
|
+
links = self.plugin.window.core.web.get_links(url)
|
367
|
+
result = {
|
368
|
+
'links': links,
|
369
|
+
}
|
370
|
+
self.ctx.urls_before.append(url)
|
371
|
+
return self.make_response(item, result)
|
372
|
+
|
373
|
+
def cmd_web_extract_images(self, item: dict) -> dict:
|
374
|
+
"""
|
375
|
+
Web extract images command
|
376
|
+
|
377
|
+
:param item: command item
|
378
|
+
:return: response item
|
379
|
+
"""
|
380
|
+
download = False
|
381
|
+
url = ""
|
382
|
+
if self.has_param(item, "url"):
|
383
|
+
url = self.get_param(item, "url")
|
384
|
+
if self.has_param(item, "download"):
|
385
|
+
download = bool(self.get_param(item, "download"))
|
386
|
+
if not url:
|
387
|
+
return self.make_response(item, "No URL provided")
|
388
|
+
images = self.plugin.window.core.web.get_images(url)
|
389
|
+
result = {
|
390
|
+
'images': images,
|
391
|
+
}
|
392
|
+
if images and download:
|
393
|
+
for img in images:
|
394
|
+
try:
|
395
|
+
path = self.plugin.window.core.web.download_image(img)
|
396
|
+
if path:
|
397
|
+
self.ctx.images_before.append(path)
|
398
|
+
except Exception as e:
|
399
|
+
print(e)
|
400
|
+
self.ctx.urls_before.append(url)
|
401
|
+
return self.make_response(item, result)
|
@@ -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.13 19:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import copy
|
@@ -1734,6 +1734,48 @@ class Patch:
|
|
1734
1734
|
'ctx.attachment.rag.history.max_items')
|
1735
1735
|
updated = True
|
1736
1736
|
|
1737
|
+
# < 2.4.38
|
1738
|
+
if old < parse_version("2.4.38"):
|
1739
|
+
print("Migrating config from < 2.4.38...")
|
1740
|
+
if 'theme.style' not in data:
|
1741
|
+
data["theme.style"] = "blocks"
|
1742
|
+
if 'audio.input.device' not in data:
|
1743
|
+
data["audio.input.device"] = "0"
|
1744
|
+
if 'audio.input.channels' not in data:
|
1745
|
+
data["audio.input.channels"] = 1
|
1746
|
+
if 'audio.input.rate' not in data:
|
1747
|
+
data["audio.input.rate"] = 44100
|
1748
|
+
self.window.core.updater.patch_css('style.light.css', True) # force update
|
1749
|
+
updated = True
|
1750
|
+
|
1751
|
+
# < 2.4.39
|
1752
|
+
if old < parse_version("2.4.39"):
|
1753
|
+
print("Migrating config from < 2.4.39...")
|
1754
|
+
if 'layout.split' not in data:
|
1755
|
+
data["layout.split"] = False
|
1756
|
+
updated = True
|
1757
|
+
|
1758
|
+
# < 2.4.40
|
1759
|
+
if old < parse_version("2.4.40"):
|
1760
|
+
print("Migrating config from < 2.4.40...")
|
1761
|
+
if 'cmd_web' in data['plugins'] \
|
1762
|
+
and 'max_result_length' in data['plugins']['cmd_web']:
|
1763
|
+
del data['plugins']['cmd_web']['max_result_length']
|
1764
|
+
if 'cmd_web' in data['plugins'] \
|
1765
|
+
and 'cmd.web_search' in data['plugins']['cmd_web']:
|
1766
|
+
del data['plugins']['cmd_web']['cmd.web_search']
|
1767
|
+
if 'cmd_web' in data['plugins'] \
|
1768
|
+
and 'cmd.web_url_open' in data['plugins']['cmd_web']:
|
1769
|
+
del data['plugins']['cmd_web']['cmd.web_url_open']
|
1770
|
+
if 'cmd_web' in data['plugins'] \
|
1771
|
+
and 'cmd.web_url_raw' in data['plugins']['cmd_web']:
|
1772
|
+
del data['plugins']['cmd_web']['cmd.web_url_raw']
|
1773
|
+
self.window.core.updater.patch_css('web-blocks.css', True) # force update
|
1774
|
+
self.window.core.updater.patch_css('web-blocks.light.css', True) # force update
|
1775
|
+
self.window.core.updater.patch_css('web-chatgpt.css', True) # force update
|
1776
|
+
self.window.core.updater.patch_css('web-chatgpt_wide.css', True) # force update
|
1777
|
+
updated = True
|
1778
|
+
|
1737
1779
|
# update file
|
1738
1780
|
migrated = False
|
1739
1781
|
if updated:
|
@@ -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.09 00:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from packaging.version import Version
|
@@ -71,6 +71,9 @@ class BaseProvider:
|
|
71
71
|
def get_meta_indexed(self):
|
72
72
|
pass
|
73
73
|
|
74
|
+
def get_item_by_id(self, id: int) -> CtxItem:
|
75
|
+
pass
|
76
|
+
|
74
77
|
def dump(self, ctx: CtxItem):
|
75
78
|
pass
|
76
79
|
|