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
pygpt_net/core/ctx/container.py
CHANGED
@@ -6,39 +6,48 @@
|
|
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
|
-
from
|
12
|
+
from typing import List
|
13
13
|
|
14
|
-
from .
|
14
|
+
from PySide6.QtWidgets import QVBoxLayout, QWidget
|
15
|
+
|
16
|
+
from pygpt_net.core.tabs.tab import Tab
|
15
17
|
from pygpt_net.ui.widget.textarea.output import ChatOutput
|
16
18
|
|
19
|
+
from .bag import Bag
|
20
|
+
from ...item.ctx import CtxItem
|
21
|
+
|
17
22
|
|
18
23
|
class Container:
|
19
24
|
def __init__(self, window=None):
|
20
25
|
"""
|
21
|
-
Context container
|
26
|
+
Context output container
|
27
|
+
|
28
|
+
:param window: Window
|
22
29
|
"""
|
23
30
|
self.window = window
|
24
31
|
self.bags = {}
|
25
32
|
self.bags[0] = Bag(window) # always create initial bag
|
26
33
|
|
27
|
-
def
|
34
|
+
def get(self, tab: Tab) -> QWidget:
|
28
35
|
"""
|
29
|
-
Register output
|
36
|
+
Register and return output
|
30
37
|
|
31
|
-
:param
|
38
|
+
:param tab: Tab
|
32
39
|
:return: Widget
|
33
40
|
"""
|
34
41
|
# plain output
|
35
42
|
output_plain = ChatOutput(self.window)
|
43
|
+
output_plain.set_tab(tab)
|
36
44
|
|
37
45
|
# web
|
38
46
|
if self.window.core.config.get("render.engine") == "web":
|
39
47
|
from pygpt_net.ui.widget.textarea.web import ChatWebOutput, CustomWebEnginePage
|
40
48
|
# build output
|
41
49
|
output_html = ChatWebOutput(self.window)
|
50
|
+
output_html.set_tab(tab)
|
42
51
|
output_html.setPage(
|
43
52
|
CustomWebEnginePage(self.window, output_html)
|
44
53
|
)
|
@@ -48,13 +57,15 @@ class Container:
|
|
48
57
|
else:
|
49
58
|
# legacy
|
50
59
|
output_html = ChatOutput(self.window)
|
60
|
+
output_html.set_tab(tab)
|
51
61
|
|
52
62
|
if 'output_plain' not in self.window.ui.nodes:
|
53
63
|
self.window.ui.nodes['output_plain'] = {}
|
54
64
|
if 'output' not in self.window.ui.nodes:
|
55
65
|
self.window.ui.nodes['output'] = {}
|
56
|
-
|
57
|
-
self.window.ui.nodes['
|
66
|
+
|
67
|
+
self.window.ui.nodes['output_plain'][tab.pid] = output_plain
|
68
|
+
self.window.ui.nodes['output'][tab.pid] = output_html
|
58
69
|
|
59
70
|
# show/hide plain/html
|
60
71
|
if self.window.core.config.get("render.plain") is True:
|
@@ -66,8 +77,8 @@ class Container:
|
|
66
77
|
|
67
78
|
# build layout
|
68
79
|
layout = QVBoxLayout()
|
69
|
-
layout.addWidget(self.window.ui.nodes['output_plain'][
|
70
|
-
layout.addWidget(self.window.ui.nodes['output'][
|
80
|
+
layout.addWidget(self.window.ui.nodes['output_plain'][tab.pid])
|
81
|
+
layout.addWidget(self.window.ui.nodes['output'][tab.pid])
|
71
82
|
layout.setContentsMargins(0, 0, 0, 0)
|
72
83
|
widget = self.window.core.tabs.from_layout(layout)
|
73
84
|
return widget
|
@@ -102,29 +113,29 @@ class Container:
|
|
102
113
|
self.bags[tab_id] = Bag(self.window) # crate new empty bag if not exists
|
103
114
|
return self.bags[tab_id]
|
104
115
|
|
105
|
-
def get_items(self) ->
|
116
|
+
def get_items(self) -> List[CtxItem]:
|
106
117
|
"""
|
107
|
-
Get items
|
118
|
+
Get ctx items
|
108
119
|
|
109
120
|
:return: Items
|
110
121
|
"""
|
111
122
|
return self.get_active_bag().get_items()
|
112
123
|
|
113
|
-
def set_items(self, items:
|
124
|
+
def set_items(self, items: List[CtxItem]):
|
114
125
|
"""
|
115
|
-
Set items
|
126
|
+
Set ctx items
|
116
127
|
|
117
128
|
:param items: Items
|
118
129
|
"""
|
119
130
|
self.get_active_bag().set_items(items)
|
120
131
|
|
121
132
|
def clear_items(self):
|
122
|
-
"""Clear items"""
|
133
|
+
"""Clear ctx items"""
|
123
134
|
self.get_active_bag().clear_items()
|
124
135
|
|
125
136
|
def count_items(self) -> int:
|
126
137
|
"""
|
127
|
-
Count items
|
138
|
+
Count ctx items
|
128
139
|
|
129
140
|
:return: Items count
|
130
141
|
"""
|
pygpt_net/core/ctx/idx.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 08:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import time
|
13
|
+
from typing import Optional
|
13
14
|
|
14
15
|
from pygpt_net.item.ctx import CtxMeta
|
15
16
|
from pygpt_net.provider.core.ctx.base import BaseProvider
|
@@ -32,7 +33,12 @@ class Idx:
|
|
32
33
|
"""
|
33
34
|
return self.window.core.ctx.get_provider()
|
34
35
|
|
35
|
-
def set_meta_indexed_by_id(
|
36
|
+
def set_meta_indexed_by_id(
|
37
|
+
self,
|
38
|
+
id: int,
|
39
|
+
doc_id: str,
|
40
|
+
ts: int
|
41
|
+
) -> bool:
|
36
42
|
"""
|
37
43
|
Update ctx meta indexed timestamp
|
38
44
|
|
@@ -43,7 +49,11 @@ class Idx:
|
|
43
49
|
"""
|
44
50
|
return self.get_provider().set_meta_indexed_by_id(id, ts)
|
45
51
|
|
46
|
-
def update_meta_indexed_by_id(
|
52
|
+
def update_meta_indexed_by_id(
|
53
|
+
self,
|
54
|
+
id: int,
|
55
|
+
doc_id: str
|
56
|
+
) -> bool:
|
47
57
|
"""
|
48
58
|
Update ctx meta indexed timestamp
|
49
59
|
|
@@ -79,7 +89,13 @@ class Idx:
|
|
79
89
|
"""
|
80
90
|
return self.get_provider().clear_meta_indexed_all()
|
81
91
|
|
82
|
-
def remove_meta_from_indexed(
|
92
|
+
def remove_meta_from_indexed(
|
93
|
+
self,
|
94
|
+
store: str,
|
95
|
+
id: int,
|
96
|
+
idx: str,
|
97
|
+
doc_id: Optional[str] = None
|
98
|
+
) -> bool:
|
83
99
|
"""
|
84
100
|
Remove ctx meta from indexed
|
85
101
|
|
@@ -114,7 +130,12 @@ class Idx:
|
|
114
130
|
self.clear_meta_indexed_by_id(id)
|
115
131
|
return True
|
116
132
|
|
117
|
-
def set_meta_as_indexed(
|
133
|
+
def set_meta_as_indexed(
|
134
|
+
self,
|
135
|
+
id: int,
|
136
|
+
idx: str,
|
137
|
+
doc_id: str
|
138
|
+
) -> bool:
|
118
139
|
"""
|
119
140
|
Set ctx meta as indexed
|
120
141
|
|
@@ -157,7 +178,13 @@ class Idx:
|
|
157
178
|
self.get_provider().update_meta_indexes_by_id(id, meta)
|
158
179
|
return True
|
159
180
|
|
160
|
-
def store_idx_data_in_meta(
|
181
|
+
def store_idx_data_in_meta(
|
182
|
+
self,
|
183
|
+
ctx: CtxMeta,
|
184
|
+
store_id: str,
|
185
|
+
idx: str,
|
186
|
+
doc_id: str
|
187
|
+
):
|
161
188
|
"""
|
162
189
|
Append index data to ctx meta object
|
163
190
|
|
@@ -176,7 +203,13 @@ class Idx:
|
|
176
203
|
current[store_id][idx][doc_id] = int(time.time()) # key = doc_id, value = last indexed timestamp
|
177
204
|
ctx.indexes = current # update ctx meta object
|
178
205
|
|
179
|
-
def remove_idx_data_from_meta(
|
206
|
+
def remove_idx_data_from_meta(
|
207
|
+
self,
|
208
|
+
ctx: CtxMeta,
|
209
|
+
store_id: str,
|
210
|
+
idx: str,
|
211
|
+
doc_id: Optional[str] = None
|
212
|
+
):
|
180
213
|
"""
|
181
214
|
Remove index data from ctx meta object
|
182
215
|
|
@@ -209,7 +242,11 @@ class Idx:
|
|
209
242
|
|
210
243
|
ctx.indexes = current # update ctx meta object
|
211
244
|
|
212
|
-
def truncate_indexed(
|
245
|
+
def truncate_indexed(
|
246
|
+
self,
|
247
|
+
store_id: Optional[str] = None,
|
248
|
+
idx: Optional[str] = None
|
249
|
+
) -> bool:
|
213
250
|
"""
|
214
251
|
Truncate ctx meta indexed timestamps and statuses
|
215
252
|
|
pygpt_net/core/ctx/output.py
CHANGED
@@ -6,9 +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 08:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
|
+
from typing import Optional, List
|
13
|
+
|
12
14
|
from pygpt_net.item.ctx import CtxItem, CtxMeta
|
13
15
|
from pygpt_net.core.tabs.tab import Tab
|
14
16
|
|
@@ -16,11 +18,28 @@ class Output:
|
|
16
18
|
def __init__(self, window=None):
|
17
19
|
"""
|
18
20
|
Context output mapping
|
21
|
+
|
22
|
+
:param window: Window
|
19
23
|
"""
|
20
24
|
self.window = window
|
21
|
-
self.mapping = {} # pid => meta.id
|
25
|
+
self.mapping = {} # [column_idx => [pid => meta.id]]
|
22
26
|
self.last_pids = {} # meta.id => pid
|
23
27
|
self.last_pid = 0 # last used PID
|
28
|
+
self.initialized = False
|
29
|
+
|
30
|
+
def init(self, force: bool = False):
|
31
|
+
"""
|
32
|
+
Initialize mappings
|
33
|
+
|
34
|
+
:param force: Force reinitialize
|
35
|
+
"""
|
36
|
+
if self.initialized and not force:
|
37
|
+
return
|
38
|
+
self.clear()
|
39
|
+
for n in range(0, self.window.core.tabs.NUM_COLS):
|
40
|
+
self.mapping[n] = {}
|
41
|
+
self.last_pids[n] = {}
|
42
|
+
self.initialized = True
|
24
43
|
|
25
44
|
def store(self, meta: CtxMeta) -> int:
|
26
45
|
"""
|
@@ -29,31 +48,20 @@ class Output:
|
|
29
48
|
:param meta: Meta
|
30
49
|
:return: PID
|
31
50
|
"""
|
51
|
+
self.init()
|
32
52
|
pid = self.window.core.tabs.get_active_pid()
|
33
|
-
# check if allowed tab
|
34
53
|
tab = self.window.core.tabs.get_tab_by_pid(pid)
|
35
54
|
if tab is None or tab.type != Tab.TAB_CHAT:
|
36
55
|
return 0
|
37
|
-
|
38
|
-
self.
|
56
|
+
col_idx = tab.column_idx
|
57
|
+
self.mapping[col_idx][pid] = meta.id
|
58
|
+
self.last_pids[col_idx][meta.id] = pid
|
39
59
|
self.last_pid = pid
|
40
60
|
tab = self.window.core.tabs.get_tab_by_pid(pid)
|
41
61
|
if tab is not None:
|
42
62
|
tab.data_id = meta.id # store meta id in tab data
|
43
63
|
return pid
|
44
64
|
|
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
65
|
def is_mapped(self, meta: CtxMeta) -> bool:
|
58
66
|
"""
|
59
67
|
Check if meta is mapped
|
@@ -61,97 +69,108 @@ class Output:
|
|
61
69
|
:param meta: Meta
|
62
70
|
:return: bool
|
63
71
|
"""
|
64
|
-
|
72
|
+
self.init()
|
73
|
+
for col_idx in self.mapping:
|
74
|
+
if meta.id in self.mapping[col_idx].values():
|
75
|
+
return True
|
76
|
+
return False
|
65
77
|
|
66
|
-
def get_meta(self, pid: int) ->
|
78
|
+
def get_meta(self, pid: int) -> Optional[int]:
|
67
79
|
"""
|
68
80
|
Get meta by PID
|
69
81
|
|
70
82
|
:param pid: PID
|
71
|
-
:return:
|
83
|
+
:return: meta ID or None
|
72
84
|
"""
|
73
|
-
|
74
|
-
|
85
|
+
self.init()
|
86
|
+
for col_idx in self.mapping:
|
87
|
+
if pid in self.mapping[col_idx]:
|
88
|
+
return self.mapping[col_idx][pid]
|
75
89
|
return
|
76
90
|
|
77
|
-
def
|
91
|
+
def prepare_meta(self, tab: Tab) -> Optional[int]:
|
92
|
+
"""
|
93
|
+
Get meta ID by PID
|
94
|
+
|
95
|
+
:param tab: Tab
|
96
|
+
:return: Meta ID or None
|
97
|
+
"""
|
98
|
+
self.init()
|
99
|
+
pid = tab.pid
|
100
|
+
col_idx = tab.column_idx
|
101
|
+
meta_id = None
|
102
|
+
if pid in self.mapping[col_idx]:
|
103
|
+
return self.mapping[col_idx][pid]
|
104
|
+
if meta_id is None:
|
105
|
+
meta_id = tab.data_id
|
106
|
+
if meta_id is not None:
|
107
|
+
self.mapping[col_idx][pid] = meta_id
|
108
|
+
self.last_pids[col_idx][meta_id] = pid
|
109
|
+
self.last_pid = pid
|
110
|
+
return meta_id
|
111
|
+
|
112
|
+
def get_mapped(self, meta: CtxMeta) -> Optional[int]:
|
78
113
|
"""
|
79
114
|
Get PID by meta
|
80
115
|
|
81
116
|
:param meta: Meta
|
82
117
|
:return: PID or None
|
83
118
|
"""
|
119
|
+
self.init()
|
84
120
|
all = []
|
85
121
|
pid = None
|
86
122
|
active_pid = self.window.core.tabs.get_active_pid()
|
87
|
-
|
123
|
+
tab = self.window.core.tabs.get_tab_by_pid(active_pid)
|
124
|
+
if tab is None:
|
125
|
+
return None
|
126
|
+
col_idx = tab.column_idx
|
127
|
+
for pid, meta_id in self.mapping[col_idx].items():
|
88
128
|
if meta_id == meta.id:
|
89
129
|
all.append(pid)
|
90
130
|
for pid in all:
|
91
|
-
if pid == active_pid: # at first check
|
131
|
+
if pid == active_pid: # at first check for current tab
|
92
132
|
return pid
|
93
133
|
return pid
|
94
134
|
|
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
135
|
def is_empty(self) -> bool:
|
128
136
|
"""
|
129
137
|
Check if mapping is empty
|
130
138
|
|
131
139
|
:return: bool
|
132
140
|
"""
|
141
|
+
self.init()
|
133
142
|
active_pid = self.window.core.tabs.get_active_pid()
|
134
|
-
|
135
|
-
|
143
|
+
for col_idx in list(self.mapping.keys()):
|
144
|
+
if active_pid in self.mapping[col_idx]:
|
145
|
+
return False
|
136
146
|
return True
|
137
147
|
|
138
|
-
def get_pid(self, meta: CtxMeta = None) -> int:
|
148
|
+
def get_pid(self, meta: Optional[CtxMeta] = None) -> Optional[int]:
|
139
149
|
"""
|
140
150
|
Get PID by meta
|
141
151
|
|
142
152
|
:param meta: Meta
|
143
153
|
:return: PID
|
144
154
|
"""
|
155
|
+
self.init()
|
156
|
+
active_pid = self.window.core.tabs.get_active_pid()
|
145
157
|
if meta is None:
|
146
|
-
return
|
158
|
+
return None
|
147
159
|
if self.is_mapped(meta):
|
148
|
-
if
|
149
|
-
return
|
150
|
-
|
151
|
-
|
152
|
-
|
160
|
+
if active_pid == self.get_mapped(meta): # if loaded in current tab
|
161
|
+
return active_pid # return current
|
162
|
+
return self.store(meta)
|
163
|
+
|
164
|
+
def clear(self):
|
165
|
+
"""
|
166
|
+
Clear mapping
|
167
|
+
"""
|
168
|
+
self.mapping = {}
|
169
|
+
self.last_pids = {}
|
170
|
+
self.last_pid = 0
|
171
|
+
self.initialized = False
|
153
172
|
|
154
|
-
def get_current(self, meta: CtxMeta = None):
|
173
|
+
def get_current(self, meta: Optional[CtxMeta] = None):
|
155
174
|
"""
|
156
175
|
Get current output node by meta
|
157
176
|
|
@@ -165,7 +184,7 @@ class Output:
|
|
165
184
|
for pid in self.window.ui.nodes['output']:
|
166
185
|
return self.window.ui.nodes['output'][pid] # get first available
|
167
186
|
|
168
|
-
def get_current_plain(self, meta: CtxMeta = None):
|
187
|
+
def get_current_plain(self, meta: Optional[CtxMeta] = None):
|
169
188
|
"""
|
170
189
|
Get current output plain node by meta
|
171
190
|
|
@@ -176,9 +195,10 @@ class Output:
|
|
176
195
|
if pid in self.window.ui.nodes['output_plain']:
|
177
196
|
return self.window.ui.nodes['output_plain'][pid]
|
178
197
|
else:
|
179
|
-
|
198
|
+
for pid in self.window.ui.nodes['output_plain']:
|
199
|
+
return self.window.ui.nodes['output_plain'][pid]
|
180
200
|
|
181
|
-
def get_by_pid(self, pid = None):
|
201
|
+
def get_by_pid(self, pid: Optional[int] = None):
|
182
202
|
"""
|
183
203
|
Get output node by PID
|
184
204
|
|
@@ -191,7 +211,7 @@ class Output:
|
|
191
211
|
for pid in self.window.ui.nodes['output']:
|
192
212
|
return self.window.ui.nodes['output'][pid] # get first available
|
193
213
|
|
194
|
-
def get_by_pid_plain(self, pid = None):
|
214
|
+
def get_by_pid_plain(self, pid: Optional[int] = None):
|
195
215
|
"""
|
196
216
|
Get output plain node by PID
|
197
217
|
|
@@ -201,9 +221,10 @@ class Output:
|
|
201
221
|
if pid in self.window.ui.nodes['output_plain']:
|
202
222
|
return self.window.ui.nodes['output_plain'][pid]
|
203
223
|
else:
|
204
|
-
|
224
|
+
for pid in self.window.ui.nodes['output_plain']:
|
225
|
+
return self.window.ui.nodes['output_plain'][pid]
|
205
226
|
|
206
|
-
def get_all(self) ->
|
227
|
+
def get_all(self) -> List:
|
207
228
|
"""
|
208
229
|
Get all output nodes
|
209
230
|
|
@@ -214,7 +235,7 @@ class Output:
|
|
214
235
|
nodes.append(node)
|
215
236
|
return nodes
|
216
237
|
|
217
|
-
def get_all_plain(self) ->
|
238
|
+
def get_all_plain(self) -> List:
|
218
239
|
"""
|
219
240
|
Get all output plain nodes
|
220
241
|
|
pygpt_net/core/ctx/reply.py
CHANGED
@@ -6,9 +6,12 @@
|
|
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
|
+
from typing import Dict, Any
|
13
|
+
|
14
|
+
|
12
15
|
class ReplyContext:
|
13
16
|
|
14
17
|
AGENT_CONTINUE = "agent.continue"
|
@@ -27,7 +30,7 @@ class ReplyContext:
|
|
27
30
|
self.input = ""
|
28
31
|
self.cmds = []
|
29
32
|
|
30
|
-
def to_dict(self) ->
|
33
|
+
def to_dict(self) -> Dict[str, Any]:
|
31
34
|
"""
|
32
35
|
Dump to dictionary
|
33
36
|
|
pygpt_net/core/db/__init__.py
CHANGED
@@ -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.14 08:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import os
|
13
13
|
import shutil
|
14
14
|
import time
|
15
|
+
from typing import Optional, Any, Dict
|
15
16
|
|
16
17
|
from sqlalchemy import create_engine, text
|
17
18
|
|
@@ -320,7 +321,7 @@ class Database:
|
|
320
321
|
self.db_path = os.path.join(self.window.core.config.path, self.db_name)
|
321
322
|
self.prepare()
|
322
323
|
|
323
|
-
def get_tables(self) ->
|
324
|
+
def get_tables(self) -> Dict[str, Dict[str, Any]]:
|
324
325
|
"""
|
325
326
|
Get tables configuration
|
326
327
|
|
@@ -402,7 +403,7 @@ class Database:
|
|
402
403
|
self.set_param_exec("db_version", migration_version, conn)
|
403
404
|
print("[DB] Executed DB migration: {}".format(migration.__class__.__name__).replace('Version', ''))
|
404
405
|
|
405
|
-
def has_migrations_to_apply(self, migrations) -> bool:
|
406
|
+
def has_migrations_to_apply(self, migrations: list) -> bool:
|
406
407
|
"""
|
407
408
|
Check if there are any migrations to apply
|
408
409
|
|
@@ -417,7 +418,7 @@ class Database:
|
|
417
418
|
break
|
418
419
|
return has_migrations
|
419
420
|
|
420
|
-
def make_backup(self) -> str
|
421
|
+
def make_backup(self) -> Optional[str]:
|
421
422
|
"""
|
422
423
|
Make backup of database before migration
|
423
424
|
|
@@ -446,7 +447,7 @@ class Database:
|
|
446
447
|
for migration in sorted_migrations:
|
447
448
|
self.apply_migration(migration, conn, db_version)
|
448
449
|
|
449
|
-
def get_param(self, key: str) -> str
|
450
|
+
def get_param(self, key: str) -> Optional[str]:
|
450
451
|
"""
|
451
452
|
Get parameter from database
|
452
453
|
|
@@ -460,7 +461,7 @@ class Database:
|
|
460
461
|
result = conn.execute(sel_stmt).fetchone()
|
461
462
|
return result[0] if result else None
|
462
463
|
|
463
|
-
def set_param(self, key: str, value:
|
464
|
+
def set_param(self, key: str, value: Any):
|
464
465
|
"""
|
465
466
|
Insert or update parameter in database
|
466
467
|
|
@@ -471,7 +472,7 @@ class Database:
|
|
471
472
|
with self.engine.begin() as conn:
|
472
473
|
self.set_param_exec(key, value, conn)
|
473
474
|
|
474
|
-
def set_param_exec(self, key: str, value:
|
475
|
+
def set_param_exec(self, key: str, value: Any, conn):
|
475
476
|
"""
|
476
477
|
Insert or update parameter in database
|
477
478
|
|
pygpt_net/core/db/viewer.py
CHANGED
@@ -6,16 +6,22 @@
|
|
6
6
|
# GitHub: https://github.com/szczyglis-dev/py-gpt #
|
7
7
|
# MIT License #
|
8
8
|
# Created By : Marcin Szczygliński #
|
9
|
-
# Updated Date: 2024.
|
9
|
+
# Updated Date: 2024.12.14 08:00:00 #
|
10
10
|
# ================================================== #
|
11
11
|
|
12
12
|
import json
|
13
|
+
from typing import Optional, List, Dict, Any
|
13
14
|
|
14
15
|
from sqlalchemy import text
|
15
16
|
|
16
17
|
|
17
18
|
class Viewer:
|
18
19
|
def __init__(self, database):
|
20
|
+
"""
|
21
|
+
Database viewer.
|
22
|
+
|
23
|
+
:param database: Database instance
|
24
|
+
"""
|
19
25
|
self.database = database
|
20
26
|
self.tables = {}
|
21
27
|
self.auto_backup = True
|
@@ -23,14 +29,14 @@ class Viewer:
|
|
23
29
|
def fetch_data(
|
24
30
|
self,
|
25
31
|
table: str,
|
26
|
-
columns:
|
32
|
+
columns: List[str],
|
27
33
|
sort_by: str,
|
28
34
|
order: str,
|
29
|
-
search_query: str = None,
|
30
|
-
search_column: str = None,
|
35
|
+
search_query: Optional[str] = None,
|
36
|
+
search_column: Optional[str] = None,
|
31
37
|
offset: int = 0,
|
32
38
|
limit: int = 100,
|
33
|
-
filters: dict = None
|
39
|
+
filters: Optional[dict] = None
|
34
40
|
) -> list:
|
35
41
|
"""
|
36
42
|
Fetch data from the database with the given parameters.
|
@@ -87,9 +93,9 @@ class Viewer:
|
|
87
93
|
def count_rows(
|
88
94
|
self,
|
89
95
|
table: str,
|
90
|
-
search_query: str = None,
|
91
|
-
search_column: str = None,
|
92
|
-
filters:
|
96
|
+
search_query: Optional[str] = None,
|
97
|
+
search_column: Optional[str] = None,
|
98
|
+
filters: Optional[Dict[str, Any]] = None
|
93
99
|
) -> int:
|
94
100
|
"""
|
95
101
|
Count the number of rows in the table with an optional search query.
|
@@ -142,7 +148,7 @@ class Viewer:
|
|
142
148
|
"""
|
143
149
|
return self.database.window.ui.debug["db"].browser.is_auto_backup()
|
144
150
|
|
145
|
-
def delete_row(self, data:
|
151
|
+
def delete_row(self, data: Dict[str, Any]):
|
146
152
|
"""
|
147
153
|
Delete row from the database.
|
148
154
|
|
@@ -165,7 +171,7 @@ class Viewer:
|
|
165
171
|
self.log(msg)
|
166
172
|
self.database.window.ui.debug["db"].browser.update_table_view()
|
167
173
|
|
168
|
-
def update_row(self, data:
|
174
|
+
def update_row(self, data: Dict[str, Any]):
|
169
175
|
"""
|
170
176
|
Update row in the database.
|
171
177
|
|
@@ -216,7 +222,7 @@ class Viewer:
|
|
216
222
|
self.log(msg)
|
217
223
|
self.database.window.ui.debug["db"].browser.update_table_view()
|
218
224
|
|
219
|
-
def truncate_table(self, data:
|
225
|
+
def truncate_table(self, data: Dict[str, Any], reset: bool = False):
|
220
226
|
"""
|
221
227
|
Truncate table in the database.
|
222
228
|
|