pygpt-net 2.4.38__py3-none-any.whl → 2.4.40__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 +19 -0
- README.md +25 -2
- pygpt_net/CHANGELOG.txt +19 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/controller/__init__.py +7 -3
- pygpt_net/controller/audio/__init__.py +9 -1
- pygpt_net/controller/calendar/__init__.py +3 -1
- pygpt_net/controller/chat/input.py +2 -1
- pygpt_net/controller/chat/render.py +8 -5
- pygpt_net/controller/ctx/__init__.py +33 -25
- pygpt_net/controller/ctx/common.py +3 -2
- pygpt_net/controller/debug/__init__.py +13 -2
- pygpt_net/controller/dialogs/confirm.py +2 -2
- pygpt_net/controller/kernel/__init__.py +2 -1
- pygpt_net/controller/lang/custom.py +2 -7
- pygpt_net/controller/lang/mapping.py +2 -2
- pygpt_net/controller/layout.py +2 -2
- pygpt_net/controller/notepad.py +14 -10
- pygpt_net/controller/theme/nodes.py +2 -5
- pygpt_net/controller/tools/__init__.py +37 -1
- pygpt_net/controller/ui/__init__.py +1 -5
- pygpt_net/controller/ui/tabs.py +295 -60
- pygpt_net/core/command.py +3 -1
- pygpt_net/core/ctx/__init__.py +16 -2
- pygpt_net/core/ctx/container.py +18 -11
- pygpt_net/core/ctx/output.py +86 -67
- pygpt_net/core/debug/tabs.py +5 -2
- pygpt_net/core/filesystem/url.py +7 -3
- pygpt_net/core/render/base.py +14 -3
- pygpt_net/core/render/markdown/renderer.py +3 -1
- pygpt_net/core/render/plain/renderer.py +3 -3
- pygpt_net/core/render/web/body.py +10 -4
- pygpt_net/core/render/web/renderer.py +213 -41
- pygpt_net/core/tabs/__init__.py +268 -98
- pygpt_net/core/tabs/tab.py +16 -4
- pygpt_net/core/web.py +127 -1
- pygpt_net/data/config/config.json +12 -5
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/modes.json +3 -3
- pygpt_net/data/css/web-blocks.css +18 -0
- pygpt_net/data/css/web-blocks.light.css +7 -0
- pygpt_net/data/css/web-chatgpt.css +8 -0
- pygpt_net/data/css/web-chatgpt_wide.css +8 -0
- pygpt_net/data/icons/split_screen.svg +1 -0
- pygpt_net/data/locale/locale.de.ini +3 -0
- pygpt_net/data/locale/locale.en.ini +6 -1
- pygpt_net/data/locale/locale.es.ini +3 -0
- pygpt_net/data/locale/locale.fr.ini +3 -0
- pygpt_net/data/locale/locale.it.ini +3 -0
- pygpt_net/data/locale/locale.pl.ini +4 -1
- pygpt_net/data/locale/locale.uk.ini +3 -0
- pygpt_net/data/locale/locale.zh.ini +3 -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 +4 -2
- pygpt_net/plugin/audio_output/__init__.py +4 -1
- pygpt_net/plugin/base/plugin.py +18 -4
- 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 +29 -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/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/debug.py +11 -1
- pygpt_net/ui/widget/filesystem/explorer.py +2 -2
- pygpt_net/ui/widget/lists/context.py +26 -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 +209 -55
- pygpt_net/ui/widget/textarea/html.py +11 -1
- pygpt_net/ui/widget/textarea/output.py +10 -1
- pygpt_net/ui/widget/textarea/web.py +49 -9
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.40.dist-info}/METADATA +26 -3
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.40.dist-info}/RECORD +105 -103
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.40.dist-info}/LICENSE +0 -0
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.40.dist-info}/WHEEL +0 -0
- {pygpt_net-2.4.38.dist-info → pygpt_net-2.4.40.dist-info}/entry_points.txt +0 -0
pygpt_net/core/ctx/__init__.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: 2024.
|
9
|
+
# Updated Date: 2024.12.13 08:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import copy
|
@@ -490,6 +490,16 @@ class Ctx:
|
|
490
490
|
for item in self.get_items():
|
491
491
|
if item.id == id:
|
492
492
|
return item
|
493
|
+
return self.fetch_item_by_id(id) # if no item found, try to fetch from DB
|
494
|
+
|
495
|
+
def fetch_item_by_id(self, id: int) -> CtxItem:
|
496
|
+
"""
|
497
|
+
Fetch ctx item by id
|
498
|
+
|
499
|
+
:param id: item id
|
500
|
+
:return: context item
|
501
|
+
"""
|
502
|
+
return self.provider.get_item_by_id(id)
|
493
503
|
|
494
504
|
def get_meta(self, reload: bool = False) -> dict:
|
495
505
|
"""
|
@@ -1361,10 +1371,13 @@ class Ctx:
|
|
1361
1371
|
"""
|
1362
1372
|
prev_ctx = CtxItem()
|
1363
1373
|
prev_ctx.urls = copy.deepcopy(ctx.urls)
|
1374
|
+
prev_ctx.urls_before = copy.deepcopy(ctx.urls_before)
|
1364
1375
|
prev_ctx.images = copy.deepcopy(ctx.images)
|
1365
1376
|
prev_ctx.images_before = copy.deepcopy(ctx.images_before)
|
1366
1377
|
prev_ctx.files = copy.deepcopy(ctx.files)
|
1378
|
+
prev_ctx.files_before = copy.deepcopy(ctx.files_before)
|
1367
1379
|
prev_ctx.attachments = copy.deepcopy(ctx.attachments)
|
1380
|
+
prev_ctx.attachments_before = copy.deepcopy(ctx.attachments_before)
|
1368
1381
|
prev_ctx.results = copy.deepcopy(ctx.results)
|
1369
1382
|
prev_ctx.index_meta = copy.deepcopy(ctx.index_meta)
|
1370
1383
|
prev_ctx.doc_ids = copy.deepcopy(ctx.doc_ids)
|
@@ -1372,7 +1385,8 @@ class Ctx:
|
|
1372
1385
|
prev_ctx.output_name = copy.deepcopy(ctx.output_name)
|
1373
1386
|
|
1374
1387
|
ctx.clear_reply() # clear current reply result
|
1375
|
-
ctx.
|
1388
|
+
if len(ctx.cmds) == 0:
|
1389
|
+
ctx.from_previous() # get result from previous if exists
|
1376
1390
|
return prev_ctx
|
1377
1391
|
|
1378
1392
|
def dump(self, ctx: CtxItem) -> str:
|
pygpt_net/core/ctx/container.py
CHANGED
@@ -6,39 +6,44 @@
|
|
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.12 04:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
|
-
from PySide6.QtWidgets import QVBoxLayout
|
12
|
+
from PySide6.QtWidgets import QVBoxLayout, QWidget
|
13
13
|
|
14
|
-
from .
|
14
|
+
from pygpt_net.core.tabs.tab import Tab
|
15
15
|
from pygpt_net.ui.widget.textarea.output import ChatOutput
|
16
16
|
|
17
|
+
from .bag import Bag
|
17
18
|
|
18
19
|
class Container:
|
19
20
|
def __init__(self, window=None):
|
20
21
|
"""
|
21
|
-
Context container
|
22
|
+
Context output container
|
23
|
+
|
24
|
+
:param window: Window
|
22
25
|
"""
|
23
26
|
self.window = window
|
24
27
|
self.bags = {}
|
25
28
|
self.bags[0] = Bag(window) # always create initial bag
|
26
29
|
|
27
|
-
def
|
30
|
+
def get(self, tab: Tab) -> QWidget:
|
28
31
|
"""
|
29
|
-
Register output
|
32
|
+
Register and return output
|
30
33
|
|
31
|
-
:param
|
34
|
+
:param tab: Tab
|
32
35
|
:return: Widget
|
33
36
|
"""
|
34
37
|
# plain output
|
35
38
|
output_plain = ChatOutput(self.window)
|
39
|
+
output_plain.set_tab(tab)
|
36
40
|
|
37
41
|
# web
|
38
42
|
if self.window.core.config.get("render.engine") == "web":
|
39
43
|
from pygpt_net.ui.widget.textarea.web import ChatWebOutput, CustomWebEnginePage
|
40
44
|
# build output
|
41
45
|
output_html = ChatWebOutput(self.window)
|
46
|
+
output_html.set_tab(tab)
|
42
47
|
output_html.setPage(
|
43
48
|
CustomWebEnginePage(self.window, output_html)
|
44
49
|
)
|
@@ -48,13 +53,15 @@ class Container:
|
|
48
53
|
else:
|
49
54
|
# legacy
|
50
55
|
output_html = ChatOutput(self.window)
|
56
|
+
output_html.set_tab(tab)
|
51
57
|
|
52
58
|
if 'output_plain' not in self.window.ui.nodes:
|
53
59
|
self.window.ui.nodes['output_plain'] = {}
|
54
60
|
if 'output' not in self.window.ui.nodes:
|
55
61
|
self.window.ui.nodes['output'] = {}
|
56
|
-
|
57
|
-
self.window.ui.nodes['
|
62
|
+
|
63
|
+
self.window.ui.nodes['output_plain'][tab.pid] = output_plain
|
64
|
+
self.window.ui.nodes['output'][tab.pid] = output_html
|
58
65
|
|
59
66
|
# show/hide plain/html
|
60
67
|
if self.window.core.config.get("render.plain") is True:
|
@@ -66,8 +73,8 @@ class Container:
|
|
66
73
|
|
67
74
|
# build layout
|
68
75
|
layout = QVBoxLayout()
|
69
|
-
layout.addWidget(self.window.ui.nodes['output_plain'][
|
70
|
-
layout.addWidget(self.window.ui.nodes['output'][
|
76
|
+
layout.addWidget(self.window.ui.nodes['output_plain'][tab.pid])
|
77
|
+
layout.addWidget(self.window.ui.nodes['output'][tab.pid])
|
71
78
|
layout.setContentsMargins(0, 0, 0, 0)
|
72
79
|
widget = self.window.core.tabs.from_layout(layout)
|
73
80
|
return widget
|
pygpt_net/core/ctx/output.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: 2024.
|
9
|
+
# Updated Date: 2024.12.09 03:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from pygpt_net.item.ctx import CtxItem, CtxMeta
|
@@ -16,11 +16,28 @@ class Output:
|
|
16
16
|
def __init__(self, window=None):
|
17
17
|
"""
|
18
18
|
Context output mapping
|
19
|
+
|
20
|
+
:param window: Window
|
19
21
|
"""
|
20
22
|
self.window = window
|
21
|
-
self.mapping = {} # pid => meta.id
|
23
|
+
self.mapping = {} # [column_idx => [pid => meta.id]]
|
22
24
|
self.last_pids = {} # meta.id => pid
|
23
25
|
self.last_pid = 0 # last used PID
|
26
|
+
self.initialized = False
|
27
|
+
|
28
|
+
def init(self, force: bool = False):
|
29
|
+
"""
|
30
|
+
Initialize mappings
|
31
|
+
|
32
|
+
:param force: Force reinitialize
|
33
|
+
"""
|
34
|
+
if self.initialized and not force:
|
35
|
+
return
|
36
|
+
self.clear()
|
37
|
+
for n in range(0, self.window.core.tabs.NUM_COLS):
|
38
|
+
self.mapping[n] = {}
|
39
|
+
self.last_pids[n] = {}
|
40
|
+
self.initialized = True
|
24
41
|
|
25
42
|
def store(self, meta: CtxMeta) -> int:
|
26
43
|
"""
|
@@ -29,31 +46,20 @@ class Output:
|
|
29
46
|
:param meta: Meta
|
30
47
|
:return: PID
|
31
48
|
"""
|
49
|
+
self.init()
|
32
50
|
pid = self.window.core.tabs.get_active_pid()
|
33
|
-
# check if allowed tab
|
34
51
|
tab = self.window.core.tabs.get_tab_by_pid(pid)
|
35
52
|
if tab is None or tab.type != Tab.TAB_CHAT:
|
36
53
|
return 0
|
37
|
-
|
38
|
-
self.
|
54
|
+
col_idx = tab.column_idx
|
55
|
+
self.mapping[col_idx][pid] = meta.id
|
56
|
+
self.last_pids[col_idx][meta.id] = pid
|
39
57
|
self.last_pid = pid
|
40
58
|
tab = self.window.core.tabs.get_tab_by_pid(pid)
|
41
59
|
if tab is not None:
|
42
60
|
tab.data_id = meta.id # store meta id in tab data
|
43
61
|
return pid
|
44
62
|
|
45
|
-
def meta_id_in_tab(self, meta_id: int) -> bool:
|
46
|
-
"""
|
47
|
-
Check if meta id is in tab
|
48
|
-
|
49
|
-
:param meta_id: Meta ID
|
50
|
-
:return: bool
|
51
|
-
"""
|
52
|
-
for pid, mid in self.mapping.items():
|
53
|
-
if mid == meta_id:
|
54
|
-
return True
|
55
|
-
return False
|
56
|
-
|
57
63
|
def is_mapped(self, meta: CtxMeta) -> bool:
|
58
64
|
"""
|
59
65
|
Check if meta is mapped
|
@@ -61,19 +67,46 @@ class Output:
|
|
61
67
|
:param meta: Meta
|
62
68
|
:return: bool
|
63
69
|
"""
|
64
|
-
|
70
|
+
self.init()
|
71
|
+
for col_idx in self.mapping:
|
72
|
+
if meta.id in self.mapping[col_idx].values():
|
73
|
+
return True
|
74
|
+
return False
|
65
75
|
|
66
|
-
def get_meta(self, pid: int) ->
|
76
|
+
def get_meta(self, pid: int) -> int or None:
|
67
77
|
"""
|
68
78
|
Get meta by PID
|
69
79
|
|
70
80
|
:param pid: PID
|
71
|
-
:return:
|
81
|
+
:return: meta ID or None
|
72
82
|
"""
|
73
|
-
|
74
|
-
|
83
|
+
self.init()
|
84
|
+
for col_idx in self.mapping:
|
85
|
+
if pid in self.mapping[col_idx]:
|
86
|
+
return self.mapping[col_idx][pid]
|
75
87
|
return
|
76
88
|
|
89
|
+
def prepare_meta(self, tab: Tab) -> int or None:
|
90
|
+
"""
|
91
|
+
Get meta ID by PID
|
92
|
+
|
93
|
+
:param tab: Tab
|
94
|
+
:return: Meta ID or None
|
95
|
+
"""
|
96
|
+
self.init()
|
97
|
+
pid = tab.pid
|
98
|
+
col_idx = tab.column_idx
|
99
|
+
meta_id = None
|
100
|
+
if pid in self.mapping[col_idx]:
|
101
|
+
return self.mapping[col_idx][pid]
|
102
|
+
if meta_id is None:
|
103
|
+
meta_id = tab.data_id
|
104
|
+
if meta_id is not None:
|
105
|
+
self.mapping[col_idx][pid] = meta_id
|
106
|
+
self.last_pids[col_idx][meta_id] = pid
|
107
|
+
self.last_pid = pid
|
108
|
+
return meta_id
|
109
|
+
|
77
110
|
def get_mapped(self, meta: CtxMeta) -> int or None:
|
78
111
|
"""
|
79
112
|
Get PID by meta
|
@@ -81,75 +114,59 @@ class Output:
|
|
81
114
|
:param meta: Meta
|
82
115
|
:return: PID or None
|
83
116
|
"""
|
117
|
+
self.init()
|
84
118
|
all = []
|
85
119
|
pid = None
|
86
120
|
active_pid = self.window.core.tabs.get_active_pid()
|
87
|
-
|
121
|
+
tab = self.window.core.tabs.get_tab_by_pid(active_pid)
|
122
|
+
if tab is None:
|
123
|
+
return None
|
124
|
+
col_idx = tab.column_idx
|
125
|
+
for pid, meta_id in self.mapping[col_idx].items():
|
88
126
|
if meta_id == meta.id:
|
89
127
|
all.append(pid)
|
90
128
|
for pid in all:
|
91
|
-
if pid == active_pid: # at first check
|
129
|
+
if pid == active_pid: # at first check for current tab
|
92
130
|
return pid
|
93
131
|
return pid
|
94
132
|
|
95
|
-
def get_mapped_last(self, meta: CtxMeta) -> int or None:
|
96
|
-
"""
|
97
|
-
Get last PID by meta
|
98
|
-
|
99
|
-
:param meta: Meta
|
100
|
-
:return: PID or None
|
101
|
-
"""
|
102
|
-
active_pid = self.window.core.tabs.get_active_pid()
|
103
|
-
if self.mapping[active_pid] == meta.id:
|
104
|
-
return active_pid # return active PID at first
|
105
|
-
if meta.id in self.last_pids:
|
106
|
-
return self.last_pids[meta.id]
|
107
|
-
return
|
108
|
-
|
109
|
-
def prepare(self, meta: CtxMeta):
|
110
|
-
"""
|
111
|
-
Clear mapping
|
112
|
-
|
113
|
-
:param meta: meta to prepare
|
114
|
-
"""
|
115
|
-
active_pid = self.window.core.tabs.get_active_pid()
|
116
|
-
if active_pid in self.mapping:
|
117
|
-
del self.mapping[active_pid] # remove from mapping
|
118
|
-
|
119
|
-
def clear(self):
|
120
|
-
"""
|
121
|
-
Clear mapping
|
122
|
-
"""
|
123
|
-
self.mapping = {}
|
124
|
-
self.last_pids = {}
|
125
|
-
self.last_pid = 0
|
126
|
-
|
127
133
|
def is_empty(self) -> bool:
|
128
134
|
"""
|
129
135
|
Check if mapping is empty
|
130
136
|
|
131
137
|
:return: bool
|
132
138
|
"""
|
139
|
+
self.init()
|
133
140
|
active_pid = self.window.core.tabs.get_active_pid()
|
134
|
-
|
135
|
-
|
141
|
+
for col_idx in list(self.mapping.keys()):
|
142
|
+
if active_pid in self.mapping[col_idx]:
|
143
|
+
return False
|
136
144
|
return True
|
137
145
|
|
138
|
-
def get_pid(self, meta: CtxMeta = None) -> int:
|
146
|
+
def get_pid(self, meta: CtxMeta = None) -> int or None:
|
139
147
|
"""
|
140
148
|
Get PID by meta
|
141
149
|
|
142
150
|
:param meta: Meta
|
143
151
|
:return: PID
|
144
152
|
"""
|
153
|
+
self.init()
|
154
|
+
active_pid = self.window.core.tabs.get_active_pid()
|
145
155
|
if meta is None:
|
146
|
-
return
|
156
|
+
return None
|
147
157
|
if self.is_mapped(meta):
|
148
|
-
if
|
149
|
-
return
|
150
|
-
|
151
|
-
|
152
|
-
|
158
|
+
if active_pid == self.get_mapped(meta): # if loaded in current tab
|
159
|
+
return active_pid # return current
|
160
|
+
return self.store(meta)
|
161
|
+
|
162
|
+
def clear(self):
|
163
|
+
"""
|
164
|
+
Clear mapping
|
165
|
+
"""
|
166
|
+
self.mapping = {}
|
167
|
+
self.last_pids = {}
|
168
|
+
self.last_pid = 0
|
169
|
+
self.initialized = False
|
153
170
|
|
154
171
|
def get_current(self, meta: CtxMeta = None):
|
155
172
|
"""
|
@@ -176,7 +193,8 @@ class Output:
|
|
176
193
|
if pid in self.window.ui.nodes['output_plain']:
|
177
194
|
return self.window.ui.nodes['output_plain'][pid]
|
178
195
|
else:
|
179
|
-
|
196
|
+
for pid in self.window.ui.nodes['output_plain']:
|
197
|
+
return self.window.ui.nodes['output_plain'][pid]
|
180
198
|
|
181
199
|
def get_by_pid(self, pid = None):
|
182
200
|
"""
|
@@ -201,7 +219,8 @@ class Output:
|
|
201
219
|
if pid in self.window.ui.nodes['output_plain']:
|
202
220
|
return self.window.ui.nodes['output_plain'][pid]
|
203
221
|
else:
|
204
|
-
|
222
|
+
for pid in self.window.ui.nodes['output_plain']:
|
223
|
+
return self.window.ui.nodes['output_plain'][pid]
|
205
224
|
|
206
225
|
def get_all(self) -> list:
|
207
226
|
"""
|
pygpt_net/core/debug/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: 2024.
|
9
|
+
# Updated Date: 2024.12.12 01:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
class TabsDebug:
|
@@ -25,7 +25,10 @@ class TabsDebug:
|
|
25
25
|
self.window.core.debug.add(self.id, 'current PID', str(self.window.controller.ui.tabs.get_current_pid()))
|
26
26
|
self.window.core.debug.add(self.id, 'current IDX', str(self.window.controller.ui.tabs.get_current_idx()))
|
27
27
|
self.window.core.debug.add(self.id, 'current Type', str(self.window.controller.ui.tabs.get_current_type()))
|
28
|
+
self.window.core.debug.add(self.id, 'current Column', str(self.window.controller.ui.tabs.get_current_column_idx()))
|
28
29
|
self.window.core.debug.add(self.id, 'last_pid', str(self.window.core.tabs.last_pid))
|
30
|
+
self.window.core.debug.add(self.id, 'locked', str(self.window.controller.ui.tabs.locked))
|
31
|
+
self.window.core.debug.add(self.id, 'col', str(self.window.controller.ui.tabs.col))
|
29
32
|
self.window.core.debug.add(self.id, 'count(pids)', str(len(self.window.core.tabs.pids)))
|
30
33
|
self.window.core.debug.add(self.id, 'count(ctx bags)', str(len(self.window.core.ctx.container.bags)))
|
31
34
|
self.window.core.debug.add(self.id, '----', '')
|
@@ -38,6 +41,6 @@ class TabsDebug:
|
|
38
41
|
|
39
42
|
# mapping PID => meta.id
|
40
43
|
self.window.core.debug.add(self.id, 'PID => meta.id', str(self.window.core.ctx.output.mapping))
|
41
|
-
self.window.core.debug.add(self.id, '(last)
|
44
|
+
self.window.core.debug.add(self.id, '(last) meta.id => PID', str(self.window.core.ctx.output.last_pids))
|
42
45
|
self.window.core.debug.add(self.id, '(last) PID', str(self.window.core.ctx.output.last_pid))
|
43
46
|
self.window.core.debug.end(self.id)
|
pygpt_net/core/filesystem/url.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: 2024.
|
9
|
+
# Updated Date: 2024.12.09 03:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from PySide6.QtCore import QUrl
|
@@ -38,14 +38,18 @@ class Url:
|
|
38
38
|
]
|
39
39
|
|
40
40
|
# JS bridge
|
41
|
-
if url.toString()
|
42
|
-
pid =
|
41
|
+
if url.toString().startswith('bridge://open_find'):
|
42
|
+
pid = int(url.toString().split(':')[2])
|
43
43
|
if pid in self.window.ui.nodes['output']:
|
44
44
|
self.window.ui.nodes['output'][pid].find_open()
|
45
45
|
return
|
46
46
|
elif url.toString() == 'bridge://escape':
|
47
47
|
self.window.controller.access.on_escape()
|
48
48
|
return
|
49
|
+
elif url.toString() == 'bridge://focus':
|
50
|
+
pid = self.window.controller.ui.tabs.get_current_pid()
|
51
|
+
if pid in self.window.ui.nodes['output']:
|
52
|
+
self.window.ui.nodes['output'][pid].on_focus_js()
|
49
53
|
|
50
54
|
# -------------
|
51
55
|
|
pygpt_net/core/render/base.py
CHANGED
@@ -6,9 +6,10 @@
|
|
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.12 04:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
|
+
from pygpt_net.core.tabs.tab import Tab
|
12
13
|
from pygpt_net.item.ctx import CtxItem, CtxMeta
|
13
14
|
|
14
15
|
|
@@ -20,6 +21,15 @@ class BaseRenderer:
|
|
20
21
|
:param window: Window instance
|
21
22
|
"""
|
22
23
|
self.window = window
|
24
|
+
self.tab = None
|
25
|
+
|
26
|
+
def set_tab(self, tab: Tab):
|
27
|
+
"""
|
28
|
+
Append tab
|
29
|
+
|
30
|
+
:param tab: Tab
|
31
|
+
"""
|
32
|
+
self.tab = tab
|
23
33
|
|
24
34
|
def prepare(self):
|
25
35
|
"""
|
@@ -218,13 +228,14 @@ class BaseRenderer:
|
|
218
228
|
"""
|
219
229
|
pass
|
220
230
|
|
221
|
-
def on_page_loaded(self, meta: CtxMeta = None):
|
231
|
+
def on_page_loaded(self, meta: CtxMeta = None, tab: Tab = None):
|
222
232
|
"""
|
223
233
|
On page loaded callback
|
224
234
|
|
225
235
|
:param meta: context meta
|
236
|
+
:param tab: Tab
|
226
237
|
"""
|
227
|
-
|
238
|
+
self.tab = tab
|
228
239
|
|
229
240
|
def on_enable_edit(self, live: bool = True):
|
230
241
|
"""
|
@@ -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
|
import re
|
@@ -50,6 +50,8 @@ class Renderer(BaseRenderer):
|
|
50
50
|
|
51
51
|
:param meta: context PID
|
52
52
|
"""
|
53
|
+
if self.tab is not None:
|
54
|
+
return self.tab.pid # get PID from tab if exists
|
53
55
|
return self.window.core.ctx.output.get_pid(meta)
|
54
56
|
|
55
57
|
def get_or_create_pid(self, meta: CtxMeta):
|
@@ -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 03:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
from datetime import datetime
|
@@ -128,7 +128,7 @@ class Renderer(BaseRenderer):
|
|
128
128
|
:param clear: True if clear all output before append
|
129
129
|
"""
|
130
130
|
if clear:
|
131
|
-
self.clear_output()
|
131
|
+
self.clear_output(meta)
|
132
132
|
|
133
133
|
i = 0
|
134
134
|
for item in items:
|
@@ -399,7 +399,7 @@ class Renderer(BaseRenderer):
|
|
399
399
|
:param meta: context meta
|
400
400
|
"""
|
401
401
|
self.reset()
|
402
|
-
self.get_output_node().clear()
|
402
|
+
self.get_output_node(meta).clear()
|
403
403
|
|
404
404
|
def clear_input(self):
|
405
405
|
"""Clear input"""
|
@@ -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.12.
|
9
|
+
# Updated Date: 2024.12.09 03:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import os
|
@@ -207,7 +207,7 @@ class Body:
|
|
207
207
|
num_str = ""
|
208
208
|
if num is not None and num_all is not None and num_all > 1:
|
209
209
|
num_str = " [{}]".format(num)
|
210
|
-
return """{icon}<
|
210
|
+
return """{icon}<a href="{url}" title="{url}">{url}</a> <small>{num}</small>""". \
|
211
211
|
format(url=url,
|
212
212
|
num=num_str,
|
213
213
|
icon=icon,
|
@@ -325,7 +325,7 @@ class Body:
|
|
325
325
|
html += "</div>"
|
326
326
|
return html
|
327
327
|
|
328
|
-
def get_html(self) -> str:
|
328
|
+
def get_html(self, pid: int) -> str:
|
329
329
|
"""
|
330
330
|
Build webview HTML code
|
331
331
|
|
@@ -370,13 +370,14 @@ class Body:
|
|
370
370
|
let scrollTimeout = null;
|
371
371
|
let prevScroll = 0;
|
372
372
|
let bridge;
|
373
|
+
let pid = """ + str(pid) + """
|
373
374
|
new QWebChannel(qt.webChannelTransport, function (channel) {
|
374
375
|
bridge = channel.objects.bridge;
|
375
376
|
});
|
376
377
|
history.scrollRestoration = "manual";
|
377
378
|
document.addEventListener('keydown', function(event) {
|
378
379
|
if (event.ctrlKey && event.key === 'f') {
|
379
|
-
window.location.href = 'bridge://open_find'; // send to bridge
|
380
|
+
window.location.href = 'bridge://open_find:' + pid; // send to bridge
|
380
381
|
event.preventDefault();
|
381
382
|
}
|
382
383
|
if (event.key === 'Escape') {
|
@@ -384,6 +385,11 @@ class Body:
|
|
384
385
|
event.preventDefault();
|
385
386
|
}
|
386
387
|
});
|
388
|
+
document.addEventListener('click', function(event) {
|
389
|
+
if (event.target.tagName !== 'A' && !event.target.closest('a')) {
|
390
|
+
window.location.href = 'bridge://focus';
|
391
|
+
}
|
392
|
+
});
|
387
393
|
function highlightCode() {
|
388
394
|
document.querySelectorAll('pre code').forEach(el => {
|
389
395
|
if (!el.classList.contains('hljs')) hljs.highlightElement(el);
|