pygpt-net 2.4.37__py3-none-any.whl → 2.4.42__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. CHANGELOG.md +37 -0
  2. README.md +176 -182
  3. pygpt_net/CHANGELOG.txt +37 -0
  4. pygpt_net/__init__.py +3 -3
  5. pygpt_net/app.py +3 -1
  6. pygpt_net/controller/__init__.py +7 -3
  7. pygpt_net/controller/access/control.py +1 -1
  8. pygpt_net/controller/access/voice.py +11 -5
  9. pygpt_net/controller/agent/experts.py +11 -6
  10. pygpt_net/controller/agent/legacy.py +8 -6
  11. pygpt_net/controller/agent/llama.py +4 -2
  12. pygpt_net/controller/assistant/__init__.py +9 -4
  13. pygpt_net/controller/assistant/batch.py +38 -21
  14. pygpt_net/controller/assistant/editor.py +7 -6
  15. pygpt_net/controller/assistant/files.py +23 -7
  16. pygpt_net/controller/assistant/store.py +20 -7
  17. pygpt_net/controller/assistant/threads.py +34 -8
  18. pygpt_net/controller/attachment.py +29 -10
  19. pygpt_net/controller/audio/__init__.py +26 -5
  20. pygpt_net/controller/calendar/__init__.py +23 -4
  21. pygpt_net/controller/calendar/note.py +57 -11
  22. pygpt_net/controller/camera.py +4 -12
  23. pygpt_net/controller/chat/__init__.py +5 -3
  24. pygpt_net/controller/chat/attachment.py +34 -7
  25. pygpt_net/controller/chat/audio.py +2 -2
  26. pygpt_net/controller/chat/command.py +4 -2
  27. pygpt_net/controller/chat/common.py +11 -4
  28. pygpt_net/controller/chat/files.py +10 -3
  29. pygpt_net/controller/chat/image.py +17 -5
  30. pygpt_net/controller/chat/input.py +10 -7
  31. pygpt_net/controller/chat/output.py +21 -6
  32. pygpt_net/controller/chat/render.py +100 -21
  33. pygpt_net/controller/chat/response.py +34 -7
  34. pygpt_net/controller/chat/stream.py +4 -2
  35. pygpt_net/controller/chat/text.py +6 -4
  36. pygpt_net/controller/command.py +11 -3
  37. pygpt_net/controller/config/__init__.py +34 -6
  38. pygpt_net/controller/config/field/checkbox.py +7 -4
  39. pygpt_net/controller/config/field/cmd.py +7 -5
  40. pygpt_net/controller/config/field/combo.py +14 -6
  41. pygpt_net/controller/config/field/dictionary.py +14 -11
  42. pygpt_net/controller/config/field/input.py +9 -6
  43. pygpt_net/controller/config/field/slider.py +11 -8
  44. pygpt_net/controller/config/field/textarea.py +8 -5
  45. pygpt_net/controller/config/placeholder.py +66 -21
  46. pygpt_net/controller/ctx/__init__.py +138 -49
  47. pygpt_net/controller/ctx/common.py +15 -4
  48. pygpt_net/controller/ctx/extra.py +11 -3
  49. pygpt_net/controller/ctx/summarizer.py +24 -5
  50. pygpt_net/controller/debug/__init__.py +27 -6
  51. pygpt_net/controller/dialogs/confirm.py +34 -7
  52. pygpt_net/controller/dialogs/debug.py +4 -2
  53. pygpt_net/controller/dialogs/info.py +7 -2
  54. pygpt_net/controller/files.py +48 -10
  55. pygpt_net/controller/finder.py +11 -5
  56. pygpt_net/controller/idx/__init__.py +10 -3
  57. pygpt_net/controller/idx/common.py +4 -2
  58. pygpt_net/controller/idx/indexer.py +25 -17
  59. pygpt_net/controller/idx/settings.py +9 -3
  60. pygpt_net/controller/kernel/__init__.py +34 -8
  61. pygpt_net/controller/kernel/reply.py +12 -3
  62. pygpt_net/controller/kernel/stack.py +5 -3
  63. pygpt_net/controller/lang/custom.py +2 -7
  64. pygpt_net/controller/lang/mapping.py +5 -3
  65. pygpt_net/controller/layout.py +2 -2
  66. pygpt_net/controller/mode.py +16 -4
  67. pygpt_net/controller/model/__init__.py +14 -3
  68. pygpt_net/controller/model/editor.py +8 -3
  69. pygpt_net/controller/notepad.py +26 -12
  70. pygpt_net/controller/painter/capture.py +23 -4
  71. pygpt_net/controller/painter/common.py +9 -7
  72. pygpt_net/controller/plugins/__init__.py +19 -5
  73. pygpt_net/controller/plugins/presets.py +15 -6
  74. pygpt_net/controller/plugins/settings.py +9 -3
  75. pygpt_net/controller/presets/__init__.py +55 -16
  76. pygpt_net/controller/presets/editor.py +26 -10
  77. pygpt_net/controller/settings/__init__.py +3 -2
  78. pygpt_net/controller/settings/editor.py +29 -7
  79. pygpt_net/controller/settings/profile.py +22 -5
  80. pygpt_net/controller/theme/__init__.py +54 -12
  81. pygpt_net/controller/theme/common.py +24 -2
  82. pygpt_net/controller/theme/markdown.py +32 -16
  83. pygpt_net/controller/theme/menu.py +26 -5
  84. pygpt_net/controller/theme/nodes.py +2 -5
  85. pygpt_net/controller/tools/__init__.py +40 -2
  86. pygpt_net/controller/ui/__init__.py +4 -6
  87. pygpt_net/controller/ui/mode.py +16 -21
  88. pygpt_net/controller/ui/tabs.py +363 -65
  89. pygpt_net/core/access/actions.py +6 -4
  90. pygpt_net/core/access/shortcuts.py +4 -3
  91. pygpt_net/core/access/voice.py +6 -5
  92. pygpt_net/core/agents/legacy.py +4 -2
  93. pygpt_net/core/agents/memory.py +7 -2
  94. pygpt_net/core/agents/observer/evaluation.py +15 -7
  95. pygpt_net/core/agents/provider.py +9 -4
  96. pygpt_net/core/agents/runner.py +61 -15
  97. pygpt_net/core/agents/tools.py +23 -5
  98. pygpt_net/core/assistants/__init__.py +6 -4
  99. pygpt_net/core/assistants/files.py +35 -12
  100. pygpt_net/core/assistants/store.py +20 -10
  101. pygpt_net/core/attachments/__init__.py +54 -15
  102. pygpt_net/core/attachments/context.py +92 -29
  103. pygpt_net/core/audio/__init__.py +74 -3
  104. pygpt_net/core/audio/context.py +7 -2
  105. pygpt_net/core/audio/whisper.py +37 -0
  106. pygpt_net/core/bridge/__init__.py +22 -6
  107. pygpt_net/core/bridge/context.py +5 -3
  108. pygpt_net/core/bridge/worker.py +2 -2
  109. pygpt_net/core/calendar/__init__.py +57 -11
  110. pygpt_net/core/chain/__init__.py +8 -2
  111. pygpt_net/core/chain/chat.py +10 -8
  112. pygpt_net/core/chain/completion.py +10 -7
  113. pygpt_net/core/command.py +62 -17
  114. pygpt_net/core/ctx/__init__.py +260 -58
  115. pygpt_net/core/ctx/bag.py +25 -4
  116. pygpt_net/core/ctx/container.py +28 -17
  117. pygpt_net/core/ctx/idx.py +45 -8
  118. pygpt_net/core/ctx/output.py +95 -74
  119. pygpt_net/core/ctx/reply.py +5 -2
  120. pygpt_net/core/db/__init__.py +8 -7
  121. pygpt_net/core/db/viewer.py +17 -11
  122. pygpt_net/core/debug/__init__.py +10 -9
  123. pygpt_net/core/debug/events.py +22 -10
  124. pygpt_net/core/debug/tabs.py +9 -3
  125. pygpt_net/core/docker/__init__.py +11 -5
  126. pygpt_net/core/docker/builder.py +11 -3
  127. pygpt_net/core/events/app.py +5 -3
  128. pygpt_net/core/events/base.py +11 -5
  129. pygpt_net/core/events/control.py +5 -3
  130. pygpt_net/core/events/event.py +17 -7
  131. pygpt_net/core/events/kernel.py +5 -3
  132. pygpt_net/core/events/render.py +5 -3
  133. pygpt_net/core/experts/__init__.py +5 -4
  134. pygpt_net/core/filesystem/__init__.py +52 -34
  135. pygpt_net/core/filesystem/actions.py +8 -5
  136. pygpt_net/core/filesystem/editor.py +13 -3
  137. pygpt_net/core/filesystem/types.py +12 -7
  138. pygpt_net/core/filesystem/url.py +7 -3
  139. pygpt_net/core/history.py +3 -2
  140. pygpt_net/core/idx/__init__.py +48 -27
  141. pygpt_net/core/idx/chat.py +51 -17
  142. pygpt_net/core/idx/context.py +6 -2
  143. pygpt_net/core/idx/indexing.py +107 -42
  144. pygpt_net/core/idx/llm.py +11 -3
  145. pygpt_net/core/idx/metadata.py +13 -3
  146. pygpt_net/core/idx/types/ctx.py +32 -6
  147. pygpt_net/core/idx/types/external.py +41 -7
  148. pygpt_net/core/idx/types/files.py +31 -6
  149. pygpt_net/core/image.py +15 -4
  150. pygpt_net/core/installer.py +2 -4
  151. pygpt_net/core/llm/__init__.py +13 -3
  152. pygpt_net/core/locale.py +34 -8
  153. pygpt_net/core/models.py +63 -17
  154. pygpt_net/core/modes.py +11 -13
  155. pygpt_net/core/notepad.py +10 -5
  156. pygpt_net/core/plugins.py +31 -19
  157. pygpt_net/core/presets.py +37 -17
  158. pygpt_net/core/profile.py +21 -7
  159. pygpt_net/core/prompt/__init__.py +10 -3
  160. pygpt_net/core/prompt/custom.py +7 -6
  161. pygpt_net/core/prompt/template.py +9 -3
  162. pygpt_net/core/render/base.py +117 -22
  163. pygpt_net/core/render/markdown/body.py +27 -7
  164. pygpt_net/core/render/markdown/renderer.py +119 -22
  165. pygpt_net/core/render/plain/body.py +22 -5
  166. pygpt_net/core/render/plain/renderer.py +97 -21
  167. pygpt_net/core/render/web/body.py +75 -25
  168. pygpt_net/core/render/web/parser.py +3 -1
  169. pygpt_net/core/render/web/renderer.py +313 -63
  170. pygpt_net/core/settings.py +10 -5
  171. pygpt_net/core/tabs/__init__.py +290 -103
  172. pygpt_net/core/tabs/tab.py +26 -5
  173. pygpt_net/core/tokens.py +47 -12
  174. pygpt_net/core/updater/__init__.py +20 -7
  175. pygpt_net/core/vision/analyzer.py +29 -6
  176. pygpt_net/core/{web.py → web/__init__.py} +29 -7
  177. pygpt_net/core/web/helpers.py +237 -0
  178. pygpt_net/data/config/config.json +15 -4
  179. pygpt_net/data/config/models.json +3 -3
  180. pygpt_net/data/config/modes.json +3 -3
  181. pygpt_net/data/config/settings.json +55 -10
  182. pygpt_net/data/config/settings_section.json +3 -0
  183. pygpt_net/data/css/style.light.css +1 -0
  184. pygpt_net/data/css/{web.css → web-blocks.css} +162 -133
  185. pygpt_net/data/css/{web.light.css → web-blocks.light.css} +7 -0
  186. pygpt_net/data/css/web-chatgpt.css +350 -0
  187. pygpt_net/data/css/web-chatgpt.dark.css +64 -0
  188. pygpt_net/data/css/web-chatgpt.light.css +75 -0
  189. pygpt_net/data/css/web-chatgpt_wide.css +350 -0
  190. pygpt_net/data/css/web-chatgpt_wide.dark.css +64 -0
  191. pygpt_net/data/css/web-chatgpt_wide.light.css +75 -0
  192. pygpt_net/data/icons/split_screen.svg +1 -0
  193. pygpt_net/data/locale/locale.de.ini +12 -0
  194. pygpt_net/data/locale/locale.en.ini +18 -2
  195. pygpt_net/data/locale/locale.es.ini +12 -0
  196. pygpt_net/data/locale/locale.fr.ini +12 -0
  197. pygpt_net/data/locale/locale.it.ini +12 -0
  198. pygpt_net/data/locale/locale.pl.ini +12 -0
  199. pygpt_net/data/locale/locale.uk.ini +12 -0
  200. pygpt_net/data/locale/locale.zh.ini +12 -0
  201. pygpt_net/data/locale/plugin.cmd_web.de.ini +2 -0
  202. pygpt_net/data/locale/plugin.cmd_web.en.ini +22 -10
  203. pygpt_net/data/locale/plugin.cmd_web.es.ini +2 -0
  204. pygpt_net/data/locale/plugin.cmd_web.fr.ini +2 -0
  205. pygpt_net/data/locale/plugin.cmd_web.it.ini +2 -0
  206. pygpt_net/data/locale/plugin.cmd_web.pl.ini +2 -0
  207. pygpt_net/data/locale/plugin.cmd_web.uk.ini +2 -0
  208. pygpt_net/data/locale/plugin.cmd_web.zh.ini +2 -0
  209. pygpt_net/data/locale/plugin.mailer.en.ini +21 -0
  210. pygpt_net/icons.qrc +1 -0
  211. pygpt_net/icons_rc.py +165 -136
  212. pygpt_net/item/ctx.py +58 -25
  213. pygpt_net/plugin/agent/__init__.py +7 -2
  214. pygpt_net/plugin/audio_input/simple.py +21 -5
  215. pygpt_net/plugin/audio_output/__init__.py +9 -1
  216. pygpt_net/plugin/base/config.py +4 -2
  217. pygpt_net/plugin/base/plugin.py +75 -23
  218. pygpt_net/plugin/base/worker.py +42 -11
  219. pygpt_net/plugin/cmd_code_interpreter/__init__.py +39 -37
  220. pygpt_net/plugin/cmd_code_interpreter/runner.py +25 -12
  221. pygpt_net/plugin/cmd_history/config.py +2 -2
  222. pygpt_net/plugin/cmd_web/__init__.py +48 -9
  223. pygpt_net/plugin/cmd_web/config.py +135 -41
  224. pygpt_net/plugin/cmd_web/websearch.py +74 -33
  225. pygpt_net/plugin/cmd_web/worker.py +142 -13
  226. pygpt_net/plugin/idx_llama_index/config.py +3 -3
  227. pygpt_net/plugin/mailer/__init__.py +123 -0
  228. pygpt_net/plugin/mailer/config.py +149 -0
  229. pygpt_net/plugin/mailer/runner.py +285 -0
  230. pygpt_net/plugin/mailer/worker.py +123 -0
  231. pygpt_net/provider/agents/base.py +5 -2
  232. pygpt_net/provider/agents/openai.py +4 -2
  233. pygpt_net/provider/agents/openai_assistant.py +4 -2
  234. pygpt_net/provider/agents/planner.py +4 -2
  235. pygpt_net/provider/agents/react.py +4 -2
  236. pygpt_net/provider/audio_output/openai_tts.py +5 -11
  237. pygpt_net/provider/core/assistant/base.py +5 -3
  238. pygpt_net/provider/core/assistant/json_file.py +8 -5
  239. pygpt_net/provider/core/assistant_file/base.py +4 -3
  240. pygpt_net/provider/core/assistant_file/db_sqlite/__init__.py +4 -3
  241. pygpt_net/provider/core/assistant_file/db_sqlite/storage.py +3 -2
  242. pygpt_net/provider/core/assistant_store/base.py +6 -4
  243. pygpt_net/provider/core/assistant_store/db_sqlite/__init__.py +5 -4
  244. pygpt_net/provider/core/assistant_store/db_sqlite/storage.py +5 -3
  245. pygpt_net/provider/core/attachment/base.py +5 -3
  246. pygpt_net/provider/core/attachment/json_file.py +4 -3
  247. pygpt_net/provider/core/calendar/base.py +5 -3
  248. pygpt_net/provider/core/calendar/db_sqlite/__init__.py +6 -5
  249. pygpt_net/provider/core/calendar/db_sqlite/storage.py +5 -4
  250. pygpt_net/provider/core/config/base.py +8 -6
  251. pygpt_net/provider/core/config/json_file.py +9 -7
  252. pygpt_net/provider/core/config/patch.py +43 -1
  253. pygpt_net/provider/core/ctx/base.py +30 -25
  254. pygpt_net/provider/core/ctx/db_sqlite/__init__.py +59 -34
  255. pygpt_net/provider/core/ctx/db_sqlite/storage.py +62 -30
  256. pygpt_net/provider/core/ctx/db_sqlite/utils.py +11 -9
  257. pygpt_net/provider/core/index/base.py +129 -23
  258. pygpt_net/provider/core/index/db_sqlite/__init__.py +130 -23
  259. pygpt_net/provider/core/index/db_sqlite/storage.py +130 -23
  260. pygpt_net/provider/core/index/db_sqlite/utils.py +4 -2
  261. pygpt_net/provider/core/mode/base.py +5 -3
  262. pygpt_net/provider/core/mode/json_file.py +7 -6
  263. pygpt_net/provider/core/model/base.py +6 -4
  264. pygpt_net/provider/core/model/json_file.py +9 -7
  265. pygpt_net/provider/core/notepad/base.py +5 -3
  266. pygpt_net/provider/core/notepad/db_sqlite/__init__.py +5 -4
  267. pygpt_net/provider/core/notepad/db_sqlite/storage.py +4 -3
  268. pygpt_net/provider/core/plugin_preset/base.py +4 -2
  269. pygpt_net/provider/core/plugin_preset/json_file.py +5 -3
  270. pygpt_net/provider/core/preset/base.py +6 -4
  271. pygpt_net/provider/core/preset/json_file.py +9 -9
  272. pygpt_net/provider/core/prompt/base.py +6 -3
  273. pygpt_net/provider/core/prompt/json_file.py +11 -6
  274. pygpt_net/provider/gpt/assistants.py +21 -11
  275. pygpt_net/provider/gpt/audio.py +6 -5
  276. pygpt_net/provider/gpt/chat.py +10 -7
  277. pygpt_net/provider/gpt/completion.py +11 -5
  278. pygpt_net/provider/gpt/image.py +9 -2
  279. pygpt_net/provider/gpt/store.py +53 -18
  280. pygpt_net/provider/gpt/vision.py +17 -11
  281. pygpt_net/provider/llms/anthropic.py +7 -2
  282. pygpt_net/provider/llms/azure_openai.py +26 -5
  283. pygpt_net/provider/llms/base.py +47 -9
  284. pygpt_net/provider/llms/google.py +7 -2
  285. pygpt_net/provider/llms/hugging_face.py +13 -3
  286. pygpt_net/provider/llms/hugging_face_api.py +18 -4
  287. pygpt_net/provider/llms/local.py +7 -2
  288. pygpt_net/provider/llms/ollama.py +30 -6
  289. pygpt_net/provider/llms/openai.py +32 -6
  290. pygpt_net/provider/vector_stores/__init__.py +45 -14
  291. pygpt_net/provider/vector_stores/base.py +35 -8
  292. pygpt_net/provider/vector_stores/chroma.py +13 -3
  293. pygpt_net/provider/vector_stores/ctx_attachment.py +31 -12
  294. pygpt_net/provider/vector_stores/elasticsearch.py +12 -3
  295. pygpt_net/provider/vector_stores/pinecode.py +12 -3
  296. pygpt_net/provider/vector_stores/redis.py +12 -3
  297. pygpt_net/provider/vector_stores/simple.py +12 -3
  298. pygpt_net/provider/vector_stores/temp.py +16 -4
  299. pygpt_net/provider/web/base.py +10 -3
  300. pygpt_net/provider/web/google_custom_search.py +9 -3
  301. pygpt_net/provider/web/microsoft_bing.py +9 -3
  302. pygpt_net/tools/__init__.py +20 -4
  303. pygpt_net/tools/audio_transcriber/__init__.py +4 -3
  304. pygpt_net/tools/base.py +28 -7
  305. pygpt_net/tools/code_interpreter/__init__.py +177 -77
  306. pygpt_net/tools/code_interpreter/ui/dialogs.py +21 -103
  307. pygpt_net/tools/code_interpreter/ui/widgets.py +284 -9
  308. pygpt_net/tools/html_canvas/__init__.py +81 -25
  309. pygpt_net/tools/html_canvas/ui/dialogs.py +46 -62
  310. pygpt_net/tools/html_canvas/ui/widgets.py +96 -3
  311. pygpt_net/tools/image_viewer/__init__.py +10 -4
  312. pygpt_net/tools/indexer/__init__.py +8 -7
  313. pygpt_net/tools/media_player/__init__.py +4 -3
  314. pygpt_net/tools/text_editor/__init__.py +36 -10
  315. pygpt_net/ui/base/context_menu.py +2 -2
  316. pygpt_net/ui/layout/chat/input.py +10 -18
  317. pygpt_net/ui/layout/chat/output.py +27 -45
  318. pygpt_net/ui/layout/ctx/ctx_list.py +13 -4
  319. pygpt_net/ui/layout/toolbox/footer.py +18 -2
  320. pygpt_net/ui/main.py +2 -2
  321. pygpt_net/ui/menu/audio.py +12 -1
  322. pygpt_net/ui/menu/config.py +7 -11
  323. pygpt_net/ui/menu/debug.py +11 -1
  324. pygpt_net/ui/menu/theme.py +9 -2
  325. pygpt_net/ui/widget/filesystem/explorer.py +2 -2
  326. pygpt_net/ui/widget/lists/context.py +27 -5
  327. pygpt_net/ui/widget/tabs/Input.py +2 -2
  328. pygpt_net/ui/widget/tabs/body.py +2 -1
  329. pygpt_net/ui/widget/tabs/layout.py +195 -0
  330. pygpt_net/ui/widget/tabs/output.py +218 -55
  331. pygpt_net/ui/widget/textarea/html.py +11 -1
  332. pygpt_net/ui/widget/textarea/output.py +10 -1
  333. pygpt_net/ui/widget/textarea/search_input.py +4 -1
  334. pygpt_net/ui/widget/textarea/web.py +49 -9
  335. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/METADATA +177 -183
  336. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/RECORD +340 -325
  337. /pygpt_net/data/css/{web.dark.css → web-blocks.dark.css} +0 -0
  338. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/LICENSE +0 -0
  339. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/WHEEL +0 -0
  340. {pygpt_net-2.4.37.dist-info → pygpt_net-2.4.42.dist-info}/entry_points.txt +0 -0
@@ -6,25 +6,29 @@
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.11.17 17:00:00 #
9
+ # Updated Date: 2024.12.12 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6.QtCore import Qt
13
13
  from PySide6.QtGui import QAction, QIcon
14
- from PySide6.QtWidgets import QPushButton, QHBoxLayout, QVBoxLayout, QSplitter, QCheckBox, QLabel, QWidget, QMenuBar
14
+ from PySide6.QtWidgets import QMenuBar
15
15
 
16
- from pygpt_net.tools.code_interpreter.ui.widgets import PythonInput, PythonOutput
16
+ from pygpt_net.tools.code_interpreter.ui.widgets import ToolWidget
17
17
  from pygpt_net.ui.widget.dialog.base import BaseDialog
18
18
  from pygpt_net.utils import trans
19
19
 
20
- class Interpreter:
21
- def __init__(self, window=None):
20
+ class Tool:
21
+ def __init__(self, window=None, tool=None):
22
22
  """
23
23
  Python interpreter dialog
24
24
 
25
25
  :param window: Window instance
26
+ :param tool: Tool instance
26
27
  """
27
28
  self.window = window
29
+ self.tool = tool # tool instance
30
+ self.layout = None
31
+ self.widget = ToolWidget(window, tool)
28
32
  self.menu_bar = None
29
33
  self.menu = {}
30
34
  self.actions = {} # menu actions
@@ -43,23 +47,23 @@ class Interpreter:
43
47
  self.actions["file.clear_output"] = QAction(QIcon(":/icons/close.svg"),
44
48
  trans("interpreter.menu.file.clear_output"))
45
49
  self.actions["file.clear_output"].triggered.connect(
46
- lambda: self.window.tools.get("interpreter").clear_output()
50
+ lambda: self.tool.clear_output()
47
51
  )
48
52
  self.actions["file.clear_history"] = QAction(QIcon(":/icons/close.svg"),
49
53
  trans("interpreter.menu.file.clear_history"))
50
54
  self.actions["file.clear_history"].triggered.connect(
51
- lambda: self.window.tools.get("interpreter").clear_history()
55
+ lambda: self.tool.clear_history()
52
56
  )
53
57
  self.actions["file.clear_all"] = QAction(QIcon(":/icons/close.svg"),
54
58
  trans("interpreter.menu.file.clear_all"))
55
59
  self.actions["file.clear_all"].triggered.connect(
56
- lambda: self.window.tools.get("interpreter").clear_all()
60
+ lambda: self.tool.clear_all()
57
61
  )
58
62
 
59
63
  self.actions["kernel.restart"] = QAction(QIcon(":/icons/reload.svg"),
60
64
  trans("interpreter.menu.kernel.restart"))
61
65
  self.actions["kernel.restart"].triggered.connect(
62
- lambda: self.window.tools.get("interpreter").restart_kernel()
66
+ lambda: self.tool.restart_kernel()
63
67
  )
64
68
 
65
69
  # add actions
@@ -71,102 +75,16 @@ class Interpreter:
71
75
 
72
76
  def setup(self):
73
77
  """Setup interpreter dialog"""
74
- self.window.interpreter = PythonOutput(self.window)
75
- self.window.interpreter.setReadOnly(True)
78
+ self.layout = self.widget.setup(all=True)
79
+ self.layout.setMenuBar(self.setup_menu()) # add menu bar
76
80
 
77
- self.window.ui.nodes['interpreter.code'] = PythonOutput(self.window)
78
- self.window.ui.nodes['interpreter.code'].textChanged.connect(
79
- lambda: self.window.tools.get("interpreter").store_history()
80
- )
81
- self.window.ui.nodes['interpreter.code'].setReadOnly(False)
82
- self.window.ui.nodes['interpreter.code'].excluded_copy_to = ["interpreter_edit"]
83
-
84
- self.window.ui.nodes['interpreter.output_label'] = QLabel(trans("interpreter.edit_label.output"))
85
- self.window.ui.nodes['interpreter.edit_label'] = QLabel(trans("interpreter.edit_label.edit"))
86
-
87
- self.window.ui.nodes['interpreter.all'] = QCheckBox(trans("interpreter.all"))
88
- self.window.ui.nodes['interpreter.all'].setChecked(True)
89
- self.window.ui.nodes['interpreter.all'].clicked.connect(
90
- lambda: self.window.tools.get("interpreter").toggle_all()
91
- )
92
-
93
- self.window.ui.nodes['interpreter.auto_clear'] = QCheckBox(trans("interpreter.auto_clear"))
94
- self.window.ui.nodes['interpreter.auto_clear'].setChecked(False)
95
- self.window.ui.nodes['interpreter.auto_clear'].clicked.connect(
96
- lambda: self.window.tools.get("interpreter").toggle_auto_clear()
97
- )
98
-
99
- self.window.ui.nodes['interpreter.ipython'] = QCheckBox("IPython")
100
- self.window.ui.nodes['interpreter.ipython'].setChecked(True)
101
- self.window.ui.nodes['interpreter.ipython'].clicked.connect(
102
- lambda: self.window.tools.get("interpreter").toggle_ipython()
103
- )
104
-
105
- self.window.ui.nodes['interpreter.btn.clear'] = QPushButton(trans("interpreter.btn.clear"))
106
- self.window.ui.nodes['interpreter.btn.clear'].clicked.connect(
107
- lambda: self.window.tools.get("interpreter").clear())
108
-
109
- self.window.ui.nodes['interpreter.btn.send'] = QPushButton(trans("interpreter.btn.send"))
110
- self.window.ui.nodes['interpreter.btn.send'].clicked.connect(
111
- lambda: self.window.tools.get("interpreter").send_input()
112
- )
113
-
114
- self.window.ui.nodes['interpreter.input'] = PythonInput(self.window)
115
- self.window.ui.nodes['interpreter.input'].setPlaceholderText(trans("interpreter.input.placeholder"))
116
- self.window.ui.nodes['interpreter.input'].excluded_copy_to = ["interpreter_input"]
117
-
118
- left_layout = QVBoxLayout()
119
- left_layout.addWidget(self.window.ui.nodes['interpreter.output_label'])
120
- left_layout.addWidget(self.window.interpreter)
121
- left_layout.setContentsMargins(0, 0, 0, 0)
122
- left_widget = QWidget()
123
- left_widget.setLayout(left_layout)
124
-
125
- right_layout = QVBoxLayout()
126
- right_layout.addWidget(self.window.ui.nodes['interpreter.edit_label'])
127
- right_layout.addWidget(self.window.ui.nodes['interpreter.code'])
128
- right_layout.setContentsMargins(0, 0, 0, 0)
129
- right_widget = QWidget()
130
- right_widget.setLayout(right_layout)
131
- right_widget.setMinimumWidth(300)
132
-
133
- self.window.ui.splitters['interpreter.columns'] = QSplitter(Qt.Horizontal)
134
- self.window.ui.splitters['interpreter.columns'].addWidget(left_widget)
135
- self.window.ui.splitters['interpreter.columns'].addWidget(right_widget)
136
-
137
- bottom_layout = QHBoxLayout()
138
- bottom_layout.addWidget(self.window.ui.nodes['interpreter.btn.clear'])
139
- bottom_layout.addWidget(self.window.ui.nodes['interpreter.ipython'])
140
- bottom_layout.addWidget(self.window.ui.nodes['interpreter.auto_clear'])
141
- bottom_layout.addStretch()
142
- bottom_layout.addWidget(self.window.ui.nodes['interpreter.all'])
143
- bottom_layout.addWidget(self.window.ui.nodes['interpreter.btn.send'])
144
-
145
- edit_layout = QVBoxLayout()
146
- edit_layout.addWidget(self.window.ui.splitters['interpreter.columns'])
147
- edit_layout.setContentsMargins(0, 0, 0, 0)
148
-
149
- edit_widget = QWidget()
150
- edit_widget.setLayout(edit_layout)
151
-
152
- self.window.ui.splitters['interpreter'] = QSplitter(Qt.Vertical)
153
- self.window.ui.splitters['interpreter'].addWidget(edit_widget)
154
- self.window.ui.splitters['interpreter'].addWidget(self.window.ui.nodes['interpreter.input'])
155
- self.window.ui.splitters['interpreter'].setStretchFactor(0, 4)
156
- self.window.ui.splitters['interpreter'].setStretchFactor(1, 1)
157
-
158
- layout = QVBoxLayout()
159
- layout.setMenuBar(self.setup_menu()) # add menu bar
160
- layout.addWidget(self.window.ui.splitters['interpreter'])
161
- layout.addLayout(bottom_layout)
162
-
163
- self.window.ui.dialog['interpreter'] = InterpreterDialog(self.window)
164
- self.window.ui.dialog['interpreter'].setLayout(layout)
81
+ self.window.ui.dialog['interpreter'] = ToolDialog(self.window)
82
+ self.window.ui.dialog['interpreter'].setLayout(self.layout)
165
83
  self.window.ui.dialog['interpreter'].setWindowTitle(trans("dialog.interpreter.title"))
166
84
  self.window.ui.dialog['interpreter'].resize(800, 500)
167
85
 
168
86
 
169
- class InterpreterDialog(BaseDialog):
87
+ class ToolDialog(BaseDialog):
170
88
  def __init__(self, window=None, id="interpreter"):
171
89
  """
172
90
  Interpreter dialog
@@ -174,7 +92,7 @@ class InterpreterDialog(BaseDialog):
174
92
  :param window: main window
175
93
  :param id: logger id
176
94
  """
177
- super(InterpreterDialog, self).__init__(window, id)
95
+ super(ToolDialog, self).__init__(window, id)
178
96
  self.window = window
179
97
 
180
98
  def closeEvent(self, event):
@@ -184,7 +102,7 @@ class InterpreterDialog(BaseDialog):
184
102
  :param event: close event
185
103
  """
186
104
  self.cleanup()
187
- super(InterpreterDialog, self).closeEvent(event)
105
+ super(ToolDialog, self).closeEvent(event)
188
106
 
189
107
  def keyPressEvent(self, event):
190
108
  """
@@ -196,7 +114,7 @@ class InterpreterDialog(BaseDialog):
196
114
  self.cleanup()
197
115
  self.close() # close dialog when the Esc key is pressed.
198
116
  else:
199
- super(InterpreterDialog, self).keyPressEvent(event)
117
+ super(ToolDialog, self).keyPressEvent(event)
200
118
 
201
119
  def cleanup(self):
202
120
  """
@@ -6,20 +6,277 @@
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.03.26 15:00:00 #
9
+ # Updated Date: 2024.12.12 01:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from PySide6 import QtCore
13
- from PySide6.QtCore import Qt
14
- from PySide6.QtWidgets import QTextEdit, QApplication
13
+ from PySide6.QtCore import Qt, QObject, Signal, Slot
14
+ from PySide6.QtGui import QTextCursor
15
+ from PySide6.QtWidgets import QTextEdit, QApplication, QVBoxLayout, QLabel, QCheckBox, QPushButton, QWidget, QSplitter, \
16
+ QHBoxLayout
15
17
 
16
18
  from pygpt_net.ui.widget.textarea.editor import BaseCodeEditor
17
19
 
20
+ from pygpt_net.utils import trans
18
21
  import pygpt_net.icons_rc
19
22
 
20
23
 
24
+ class ToolWidget:
25
+ def __init__(self, window=None, tool=None):
26
+ """
27
+ Python Code Interpreter
28
+
29
+ :param window: Window instance
30
+ :param tool: Tool instance
31
+ """
32
+ self.window = window # window instance
33
+ self.tool = tool # tool instance
34
+ self.history = None # history
35
+ self.input = None # input
36
+ self.output = None # output
37
+ self.checkbox_all = None # all checkbox
38
+ self.checkbox_auto_clear = None # auto clear checkbox
39
+ self.checkbox_ipython = None # IPython checkbox
40
+ self.btn_send = None # send button
41
+ self.btn_clear = None # clear button
42
+ self.label_output = None # output label
43
+ self.label_history = None # history label
44
+
45
+ def setup(self, all: bool = True) -> QVBoxLayout:
46
+ """
47
+ Setup widget body
48
+
49
+ :param all: with all widgets
50
+ :return: QVBoxLayout
51
+ """
52
+ self.output = PythonOutput(self.window, self.tool)
53
+ self.output.setReadOnly(True)
54
+
55
+ if all:
56
+ self.history = PythonOutput(self.window, self.tool)
57
+ self.history.textChanged.connect(
58
+ lambda: self.tool.store_history(self)
59
+ )
60
+ self.history.setReadOnly(False)
61
+ self.history.excluded_copy_to = ["interpreter_edit"]
62
+
63
+ self.label_output = QLabel(trans("interpreter.edit_label.output"))
64
+ self.label_history = QLabel(trans("interpreter.edit_label.edit"))
65
+
66
+ if all:
67
+ self.checkbox_all = QCheckBox(trans("interpreter.all"))
68
+ self.checkbox_all.setChecked(True)
69
+ self.checkbox_all.clicked.connect(
70
+ lambda: self.tool.toggle_all(self)
71
+ )
72
+
73
+ self.checkbox_auto_clear = QCheckBox(trans("interpreter.auto_clear"))
74
+ self.checkbox_auto_clear.setChecked(False)
75
+ self.checkbox_auto_clear.clicked.connect(
76
+ lambda: self.tool.toggle_auto_clear(self)
77
+ )
78
+
79
+ self.checkbox_ipython = QCheckBox("IPython")
80
+ self.checkbox_ipython.setChecked(True)
81
+ self.checkbox_ipython.clicked.connect(
82
+ lambda: self.tool.toggle_ipython(self)
83
+ )
84
+
85
+ self.btn_clear = QPushButton(trans("interpreter.btn.clear"))
86
+ self.btn_clear.clicked.connect(
87
+ lambda: self.tool.clear(self)
88
+ )
89
+
90
+ self.btn_send = QPushButton(trans("interpreter.btn.send"))
91
+ self.btn_send.clicked.connect(
92
+ lambda: self.tool.send_input(self)
93
+ )
94
+
95
+ self.input = PythonInput(self.window, self.tool, self)
96
+ self.input.setPlaceholderText(trans("interpreter.input.placeholder"))
97
+ self.input.excluded_copy_to = ["interpreter_input"]
98
+
99
+ left_layout = QVBoxLayout()
100
+ left_layout.addWidget(self.label_output)
101
+ left_layout.addWidget(self.output)
102
+ left_layout.setContentsMargins(0, 0, 0, 0)
103
+ left_widget = QWidget()
104
+ left_widget.setLayout(left_layout)
105
+
106
+ self.window.ui.splitters['interpreter.columns'] = QSplitter(Qt.Horizontal)
107
+ self.window.ui.splitters['interpreter.columns'].addWidget(left_widget)
108
+
109
+ if all:
110
+ right_layout = QVBoxLayout()
111
+ right_layout.addWidget(self.label_history)
112
+ right_layout.addWidget(self.history)
113
+ right_layout.setContentsMargins(0, 0, 0, 0)
114
+ right_widget = QWidget()
115
+ right_widget.setLayout(right_layout)
116
+ right_widget.setMinimumWidth(300)
117
+ self.window.ui.splitters['interpreter.columns'].addWidget(right_widget)
118
+
119
+ bottom_layout = QHBoxLayout()
120
+ bottom_layout.addWidget(self.btn_clear)
121
+ bottom_layout.addWidget(self.checkbox_ipython)
122
+ bottom_layout.addWidget(self.checkbox_auto_clear)
123
+ bottom_layout.addStretch()
124
+ if all:
125
+ bottom_layout.addWidget(self.checkbox_all)
126
+ bottom_layout.addWidget(self.btn_send)
127
+
128
+ edit_layout = QVBoxLayout()
129
+ edit_layout.addWidget(self.window.ui.splitters['interpreter.columns'])
130
+ edit_layout.setContentsMargins(0, 0, 0, 0)
131
+ edit_widget = QWidget()
132
+ edit_widget.setLayout(edit_layout)
133
+
134
+ self.window.ui.splitters['interpreter'] = QSplitter(Qt.Vertical)
135
+ self.window.ui.splitters['interpreter'].addWidget(edit_widget)
136
+ self.window.ui.splitters['interpreter'].addWidget(self.input)
137
+ self.window.ui.splitters['interpreter'].setStretchFactor(0, 4)
138
+ self.window.ui.splitters['interpreter'].setStretchFactor(1, 1)
139
+
140
+ # connect signals
141
+ self.tool.signals.update.connect(self.set_output)
142
+ self.tool.signals.update_history.connect(self.set_history)
143
+ self.tool.signals.clear_history.connect(self.clear_history)
144
+ self.tool.signals.clear_output.connect(self.clear_output)
145
+ self.tool.signals.focus_input.connect(self.set_focus)
146
+ self.tool.signals.append_input.connect(self.append_to_input)
147
+ self.tool.signals.update_input.connect(self.set_input)
148
+ self.tool.signals.set_checkbox_all.connect(self.set_checkbox_all)
149
+ self.tool.signals.set_checkbox_auto_clear.connect(self.set_checkbox_auto_clear)
150
+ self.tool.signals.set_checkbox_ipython.connect(self.set_checkbox_ipython)
151
+ self.tool.signals.toggle_all_visible.connect(self.toggle_all_visible)
152
+
153
+ layout = QVBoxLayout()
154
+ layout.addWidget(self.window.ui.splitters['interpreter'])
155
+ layout.addLayout(bottom_layout)
156
+ return layout
157
+
158
+ @Slot(str, str)
159
+ def set_output(self, output: str, type="stdout"):
160
+ """
161
+ Set output content
162
+
163
+ :param output: Content
164
+ :param type: Output type
165
+ """
166
+ area = self.output
167
+ if type == "stdin":
168
+ data = ">> " + str(output)
169
+ else:
170
+ data = str(output)
171
+ cur = area.textCursor()
172
+ cur.movePosition(QTextCursor.End)
173
+ s = data + "\n"
174
+ while s:
175
+ head, sep, s = s.partition("\n")
176
+ cur.insertText(head)
177
+ if sep: # New line if LF
178
+ cur.insertText("\n")
179
+ area.setTextCursor(cur)
180
+
181
+ @Slot()
182
+ def set_history(self, data: str):
183
+ """
184
+ Set history
185
+
186
+ :param data: history data
187
+ """
188
+ if not self.history:
189
+ return
190
+ self.history.setPlainText(data)
191
+ cur = self.history.textCursor()
192
+ cur.movePosition(QTextCursor.End)
193
+ self.history.setTextCursor(cur)
194
+
195
+ @Slot()
196
+ def append_to_input(self, data: str):
197
+ """
198
+ Append data to input
199
+
200
+ :param data: Data
201
+ """
202
+ current = self.input.toPlainText()
203
+ if current:
204
+ current += "\n"
205
+ current += data
206
+ self.input.setPlainText(current)
207
+
208
+ @Slot(str)
209
+ def set_input(self, data: str):
210
+ """
211
+ Set input
212
+
213
+ :param data: Data
214
+ """
215
+ self.input.setPlainText(data)
216
+
217
+ @Slot()
218
+ def clear_history(self):
219
+ """Clear input"""
220
+ if not self.history:
221
+ return
222
+ self.history.clear()
223
+
224
+ @Slot()
225
+ def clear_output(self):
226
+ """Clear output"""
227
+ self.output.clear()
228
+
229
+ @Slot()
230
+ def set_focus(self):
231
+ """Set focus to input"""
232
+ self.input.setFocus()
233
+
234
+ @Slot(bool)
235
+ def set_checkbox_all(self, value: bool):
236
+ """
237
+ Set checkbox all
238
+
239
+ :param value: Value
240
+ """
241
+ if not self.checkbox_all:
242
+ return
243
+ self.checkbox_all.setChecked(value)
244
+
245
+ @Slot(bool)
246
+ def set_checkbox_auto_clear(self, value: bool):
247
+ """
248
+ Set checkbox auto clear
249
+
250
+ :param value: Value
251
+ """
252
+ self.checkbox_auto_clear.setChecked(value)
253
+
254
+ @Slot(bool)
255
+ def set_checkbox_ipython(self, value: bool):
256
+ """
257
+ Set checkbox IPython
258
+
259
+ :param value: Value
260
+ """
261
+ self.checkbox_ipython.setChecked(value)
262
+
263
+ @Slot(bool)
264
+ def toggle_all_visible(self, value: bool):
265
+ """
266
+ Toggle all visible
267
+
268
+ :param value: Value
269
+ """
270
+ if not self.checkbox_all:
271
+ return
272
+ if value:
273
+ self.checkbox_all.setVisible(True)
274
+ else:
275
+ self.checkbox_all.setVisible(False)
276
+
277
+
21
278
  class PythonInput(QTextEdit):
22
- def __init__(self, window=None):
279
+ def __init__(self, window=None, tool=None, widget=None):
23
280
  """
24
281
  Python interpreter input
25
282
 
@@ -27,6 +284,8 @@ class PythonInput(QTextEdit):
27
284
  """
28
285
  super(PythonInput, self).__init__(window)
29
286
  self.window = window
287
+ self.tool = tool
288
+ self.widget = widget
30
289
  self.setAcceptRichText(False)
31
290
  self.value = 12
32
291
  self.max_font_size = 42
@@ -35,7 +294,7 @@ class PythonInput(QTextEdit):
35
294
  self.default_stylesheet = ""
36
295
  self.setStyleSheet(self.default_stylesheet)
37
296
  self.textChanged.connect(
38
- lambda: self.window.tools.get("interpreter").update_input()
297
+ lambda: self.tool.update_input()
39
298
  )
40
299
  self.setFocus()
41
300
 
@@ -60,11 +319,11 @@ class PythonInput(QTextEdit):
60
319
  if mode == 2: # Shift + Enter
61
320
  modifiers = QApplication.keyboardModifiers()
62
321
  if modifiers == QtCore.Qt.ShiftModifier:
63
- self.window.tools.get("interpreter").send_input()
322
+ self.tool.send_input(self.widget)
64
323
  else: # Enter
65
324
  modifiers = QApplication.keyboardModifiers()
66
325
  if modifiers != QtCore.Qt.ShiftModifier:
67
- self.window.tools.get("interpreter").send_input()
326
+ self.tool.send_input(self.widget)
68
327
  self.setFocus()
69
328
 
70
329
  def wheelEvent(self, event):
@@ -89,7 +348,7 @@ class PythonInput(QTextEdit):
89
348
 
90
349
 
91
350
  class PythonOutput(BaseCodeEditor):
92
- def __init__(self, window=None):
351
+ def __init__(self, window=None, tool=None):
93
352
  """
94
353
  Python interpreter output
95
354
 
@@ -97,6 +356,7 @@ class PythonOutput(BaseCodeEditor):
97
356
  """
98
357
  super(PythonOutput, self).__init__(window)
99
358
  self.window = window
359
+ self.tool = tool
100
360
  self.setReadOnly(True)
101
361
  self.value = 12
102
362
  self.max_font_size = 42
@@ -108,4 +368,19 @@ class PythonOutput(BaseCodeEditor):
108
368
  def clear_content(self):
109
369
  """Clear content"""
110
370
  super(PythonOutput, self).clear_content()
111
- self.window.tools.get("interpreter").save_output()
371
+ self.tool.save_output()
372
+
373
+
374
+ class ToolSignals(QObject):
375
+ update = Signal(str, str) # content, type
376
+ update_history = Signal(str) # content
377
+ update_input = Signal(str) # content
378
+ append_input = Signal(str) # content
379
+ reload = Signal(str) # path
380
+ clear_history = Signal()
381
+ clear_output = Signal()
382
+ focus_input = Signal()
383
+ set_checkbox_all = Signal(bool)
384
+ set_checkbox_auto_clear = Signal(bool)
385
+ set_checkbox_ipython = Signal(bool)
386
+ toggle_all_visible = Signal(bool)