pygpt-net 2.6.1__py3-none-any.whl → 2.6.6__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 (131) hide show
  1. pygpt_net/CHANGELOG.txt +23 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +20 -1
  4. pygpt_net/config.py +55 -65
  5. pygpt_net/controller/__init__.py +5 -2
  6. pygpt_net/controller/calendar/note.py +101 -126
  7. pygpt_net/controller/chat/chat.py +38 -35
  8. pygpt_net/controller/chat/render.py +154 -214
  9. pygpt_net/controller/chat/response.py +5 -3
  10. pygpt_net/controller/chat/stream.py +92 -27
  11. pygpt_net/controller/config/config.py +39 -42
  12. pygpt_net/controller/config/field/checkbox.py +16 -12
  13. pygpt_net/controller/config/field/checkbox_list.py +36 -31
  14. pygpt_net/controller/config/field/cmd.py +51 -57
  15. pygpt_net/controller/config/field/combo.py +33 -16
  16. pygpt_net/controller/config/field/dictionary.py +48 -55
  17. pygpt_net/controller/config/field/input.py +50 -32
  18. pygpt_net/controller/config/field/slider.py +40 -45
  19. pygpt_net/controller/config/field/textarea.py +20 -6
  20. pygpt_net/controller/config/placeholder.py +110 -231
  21. pygpt_net/controller/ctx/common.py +48 -48
  22. pygpt_net/controller/ctx/ctx.py +91 -132
  23. pygpt_net/controller/lang/mapping.py +57 -95
  24. pygpt_net/controller/lang/plugins.py +64 -55
  25. pygpt_net/controller/lang/settings.py +39 -38
  26. pygpt_net/controller/layout/layout.py +176 -109
  27. pygpt_net/controller/mode/mode.py +88 -85
  28. pygpt_net/controller/model/model.py +73 -73
  29. pygpt_net/controller/plugins/plugins.py +209 -223
  30. pygpt_net/controller/plugins/presets.py +54 -55
  31. pygpt_net/controller/plugins/settings.py +54 -69
  32. pygpt_net/controller/presets/editor.py +33 -88
  33. pygpt_net/controller/presets/experts.py +20 -1
  34. pygpt_net/controller/presets/presets.py +293 -298
  35. pygpt_net/controller/settings/profile.py +16 -4
  36. pygpt_net/controller/theme/theme.py +72 -81
  37. pygpt_net/controller/ui/mode.py +118 -186
  38. pygpt_net/controller/ui/tabs.py +69 -90
  39. pygpt_net/controller/ui/ui.py +47 -56
  40. pygpt_net/controller/ui/vision.py +24 -23
  41. pygpt_net/core/agents/runner.py +15 -7
  42. pygpt_net/core/bridge/bridge.py +5 -5
  43. pygpt_net/core/command/command.py +149 -219
  44. pygpt_net/core/ctx/ctx.py +94 -146
  45. pygpt_net/core/debug/debug.py +48 -58
  46. pygpt_net/core/experts/experts.py +3 -3
  47. pygpt_net/core/models/models.py +74 -112
  48. pygpt_net/core/modes/modes.py +13 -21
  49. pygpt_net/core/plugins/plugins.py +154 -177
  50. pygpt_net/core/presets/presets.py +103 -176
  51. pygpt_net/core/render/web/body.py +217 -215
  52. pygpt_net/core/render/web/renderer.py +330 -474
  53. pygpt_net/core/text/utils.py +28 -44
  54. pygpt_net/core/tokens/tokens.py +104 -203
  55. pygpt_net/data/config/config.json +3 -3
  56. pygpt_net/data/config/models.json +3 -3
  57. pygpt_net/data/locale/locale.de.ini +2 -0
  58. pygpt_net/data/locale/locale.en.ini +2 -0
  59. pygpt_net/data/locale/locale.es.ini +2 -0
  60. pygpt_net/data/locale/locale.fr.ini +2 -0
  61. pygpt_net/data/locale/locale.it.ini +2 -0
  62. pygpt_net/data/locale/locale.pl.ini +3 -1
  63. pygpt_net/data/locale/locale.uk.ini +2 -0
  64. pygpt_net/data/locale/locale.zh.ini +2 -0
  65. pygpt_net/item/ctx.py +141 -139
  66. pygpt_net/plugin/agent/plugin.py +2 -1
  67. pygpt_net/plugin/audio_output/plugin.py +5 -2
  68. pygpt_net/plugin/base/plugin.py +101 -85
  69. pygpt_net/plugin/bitbucket/__init__.py +12 -0
  70. pygpt_net/plugin/bitbucket/config.py +267 -0
  71. pygpt_net/plugin/bitbucket/plugin.py +126 -0
  72. pygpt_net/plugin/bitbucket/worker.py +569 -0
  73. pygpt_net/plugin/cmd_code_interpreter/plugin.py +3 -2
  74. pygpt_net/plugin/cmd_custom/plugin.py +3 -2
  75. pygpt_net/plugin/cmd_files/plugin.py +3 -2
  76. pygpt_net/plugin/cmd_history/plugin.py +3 -2
  77. pygpt_net/plugin/cmd_mouse_control/plugin.py +5 -2
  78. pygpt_net/plugin/cmd_serial/plugin.py +3 -2
  79. pygpt_net/plugin/cmd_system/plugin.py +3 -6
  80. pygpt_net/plugin/cmd_web/plugin.py +3 -2
  81. pygpt_net/plugin/experts/plugin.py +2 -2
  82. pygpt_net/plugin/facebook/__init__.py +12 -0
  83. pygpt_net/plugin/facebook/config.py +359 -0
  84. pygpt_net/plugin/facebook/plugin.py +113 -0
  85. pygpt_net/plugin/facebook/worker.py +698 -0
  86. pygpt_net/plugin/github/__init__.py +12 -0
  87. pygpt_net/plugin/github/config.py +441 -0
  88. pygpt_net/plugin/github/plugin.py +126 -0
  89. pygpt_net/plugin/github/worker.py +674 -0
  90. pygpt_net/plugin/google/__init__.py +12 -0
  91. pygpt_net/plugin/google/config.py +367 -0
  92. pygpt_net/plugin/google/plugin.py +126 -0
  93. pygpt_net/plugin/google/worker.py +826 -0
  94. pygpt_net/plugin/idx_llama_index/plugin.py +3 -2
  95. pygpt_net/plugin/mailer/plugin.py +3 -5
  96. pygpt_net/plugin/openai_vision/plugin.py +3 -2
  97. pygpt_net/plugin/real_time/plugin.py +52 -60
  98. pygpt_net/plugin/slack/__init__.py +12 -0
  99. pygpt_net/plugin/slack/config.py +349 -0
  100. pygpt_net/plugin/slack/plugin.py +115 -0
  101. pygpt_net/plugin/slack/worker.py +639 -0
  102. pygpt_net/plugin/telegram/__init__.py +12 -0
  103. pygpt_net/plugin/telegram/config.py +308 -0
  104. pygpt_net/plugin/telegram/plugin.py +117 -0
  105. pygpt_net/plugin/telegram/worker.py +563 -0
  106. pygpt_net/plugin/twitter/__init__.py +12 -0
  107. pygpt_net/plugin/twitter/config.py +491 -0
  108. pygpt_net/plugin/twitter/plugin.py +125 -0
  109. pygpt_net/plugin/twitter/worker.py +837 -0
  110. pygpt_net/provider/agents/llama_index/legacy/openai_assistant.py +35 -3
  111. pygpt_net/tools/code_interpreter/tool.py +0 -1
  112. pygpt_net/tools/translator/tool.py +1 -1
  113. pygpt_net/ui/base/config_dialog.py +86 -100
  114. pygpt_net/ui/base/context_menu.py +48 -46
  115. pygpt_net/ui/dialog/preset.py +34 -77
  116. pygpt_net/ui/layout/ctx/ctx_list.py +10 -6
  117. pygpt_net/ui/layout/toolbox/presets.py +41 -41
  118. pygpt_net/ui/main.py +49 -31
  119. pygpt_net/ui/tray.py +61 -60
  120. pygpt_net/ui/widget/calendar/select.py +86 -70
  121. pygpt_net/ui/widget/lists/attachment.py +86 -44
  122. pygpt_net/ui/widget/lists/base_list_combo.py +85 -33
  123. pygpt_net/ui/widget/lists/context.py +135 -188
  124. pygpt_net/ui/widget/lists/preset.py +59 -61
  125. pygpt_net/ui/widget/textarea/web.py +161 -48
  126. pygpt_net/utils.py +8 -1
  127. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/METADATA +164 -2
  128. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/RECORD +131 -103
  129. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/LICENSE +0 -0
  130. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/WHEEL +0 -0
  131. {pygpt_net-2.6.1.dist-info → pygpt_net-2.6.6.dist-info}/entry_points.txt +0 -0
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2025.08.01 19:00:00 #
9
+ # Updated Date: 2025.08.15 23:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, List
@@ -24,6 +24,13 @@ from pygpt_net.item.ctx import CtxItem, CtxMeta
24
24
 
25
25
 
26
26
  class Render:
27
+
28
+ _STATE_EVENTS = (
29
+ RenderEvent.STATE_IDLE,
30
+ RenderEvent.STATE_BUSY,
31
+ RenderEvent.STATE_ERROR,
32
+ )
33
+
27
34
  def __init__(self, window=None):
28
35
  """
29
36
  Render controller
@@ -36,131 +43,130 @@ class Render:
36
43
  self.web_renderer = WebRenderer(window)
37
44
  self.engine = None
38
45
  self.scroll = 0
46
+ self.renderer = None
39
47
 
40
- def setup(self):
48
+ def setup(self) -> None:
41
49
  """Setup render"""
42
50
  self.engine = self.window.core.config.get("render.engine")
51
+ if self.window.core.config.get('render.plain'):
52
+ self.renderer = self.plaintext_renderer
53
+ else:
54
+ self.renderer = self.web_renderer if self.engine == "web" else self.markdown_renderer
43
55
 
44
- def prepare(self):
56
+ def prepare(self) -> None:
45
57
  """Prepare render"""
46
58
  self.markdown_renderer.prepare()
47
59
  self.plaintext_renderer.prepare()
48
60
  self.web_renderer.prepare()
49
61
 
50
- def handle(self, event: RenderEvent):
62
+ def handle(self, event: RenderEvent) -> None:
51
63
  """
52
64
  Handle render event
53
65
 
54
66
  :param event: RenderEvent
55
67
  """
56
68
  name = event.name
57
- data = event.data
58
- if data is None:
59
- data = {}
60
-
61
- chunk = data.get("chunk", "")
62
- begin = data.get("begin", False)
63
- stream = data.get("stream", False)
64
- ctx = data.get("ctx")
65
- meta = data.get("meta")
66
- tool_data = data.get("tool_data")
67
- items = data.get("items")
68
- clear = data.get("clear", False)
69
- flush = data.get("flush", False)
70
- append = data.get("append", False)
71
- footer = data.get("footer", False)
72
- initialized = data.get("initialized", False)
73
- tab = data.get("tab")
69
+ data = event.data or {}
74
70
 
75
71
  if name == RenderEvent.BEGIN:
76
- self.begin(meta, ctx, stream)
72
+ self.begin(data.get("meta"), data.get("ctx"), data.get("stream", False))
77
73
  elif name == RenderEvent.END:
78
- self.end(meta, ctx, stream)
74
+ self.end(data.get("meta"), data.get("ctx"), data.get("stream", False))
79
75
  elif name == RenderEvent.RELOAD:
80
76
  self.reload()
81
77
  elif name == RenderEvent.RESET:
82
- self.reset(meta)
78
+ self.reset(data.get("meta"))
83
79
  elif name == RenderEvent.PREPARE:
84
80
  self.prepare()
85
81
 
86
82
  elif name == RenderEvent.STREAM_BEGIN:
87
- self.stream_begin(meta, ctx)
83
+ self.stream_begin(data.get("meta"), data.get("ctx"))
88
84
  elif name == RenderEvent.STREAM_APPEND:
89
- self.append_chunk(meta, ctx, chunk, begin)
85
+ self.instance().append_chunk(
86
+ data.get("meta"),
87
+ data.get("ctx"),
88
+ data.get("chunk", ""),
89
+ data.get("begin", False),
90
+ )
90
91
  elif name == RenderEvent.STREAM_NEXT:
91
- self.next_chunk(meta, ctx)
92
+ self.next_chunk(data.get("meta"), data.get("ctx"))
92
93
  elif name == RenderEvent.STREAM_END:
93
- self.stream_end(meta, ctx)
94
+ self.stream_end(data.get("meta"), data.get("ctx"))
94
95
 
95
96
  elif name == RenderEvent.ON_PAGE_LOAD:
96
- self.on_page_loaded(meta, tab)
97
+ self.on_page_loaded(data.get("meta"), data.get("tab"))
97
98
  elif name == RenderEvent.ON_THEME_CHANGE:
98
99
  self.on_theme_change()
99
100
  elif name == RenderEvent.ON_LOAD:
100
- self.on_load(meta)
101
+ self.on_load(data.get("meta"))
101
102
  elif name == RenderEvent.FRESH:
102
- self.fresh(meta)
103
+ self.fresh(data.get("meta"))
103
104
  elif name == RenderEvent.ON_TS_ENABLE:
104
- self.on_enable_timestamp(live=initialized)
105
+ self.on_enable_timestamp(live=data.get("initialized", False))
105
106
  elif name == RenderEvent.ON_TS_DISABLE:
106
- self.on_disable_timestamp(live=initialized)
107
+ self.on_disable_timestamp(live=data.get("initialized", False))
107
108
  elif name == RenderEvent.ON_EDIT_ENABLE:
108
- self.on_enable_edit(live=initialized)
109
+ self.on_enable_edit(live=data.get("initialized", False))
109
110
  elif name == RenderEvent.ON_EDIT_DISABLE:
110
- self.on_disable_edit(live=initialized)
111
+ self.on_disable_edit(live=data.get("initialized", False))
111
112
  elif name == RenderEvent.ON_SWITCH:
112
113
  self.switch()
113
114
 
114
115
  elif name == RenderEvent.CLEAR_INPUT:
115
116
  self.clear_input()
116
117
  elif name == RenderEvent.CLEAR_OUTPUT:
117
- self.clear_output(meta)
118
+ self.clear_output(data.get("meta"))
118
119
  elif name == RenderEvent.CLEAR_ALL:
119
120
  self.clear_all()
120
121
  elif name == RenderEvent.CLEAR:
121
- self.clear(meta)
122
+ self.clear(data.get("meta"))
122
123
 
123
124
  elif name == RenderEvent.TOOL_UPDATE:
124
- self.tool_output_update(meta, tool_data)
125
+ self.tool_output_update(data.get("meta"), data.get("tool_data"))
125
126
  elif name == RenderEvent.TOOL_CLEAR:
126
- self.tool_output_clear(meta)
127
+ self.tool_output_clear(data.get("meta"))
127
128
  elif name == RenderEvent.TOOL_BEGIN:
128
- self.tool_output_begin(meta)
129
+ self.tool_output_begin(data.get("meta"))
129
130
  elif name == RenderEvent.TOOL_END:
130
131
  self.tool_output_end()
131
132
 
132
133
  elif name == RenderEvent.CTX_APPEND:
133
- self.append_context(meta, items, clear)
134
+ self.append_context(data.get("meta"), data.get("items"), data.get("clear", True))
134
135
  elif name == RenderEvent.INPUT_APPEND:
135
- self.append_input(meta, ctx, flush, append)
136
+ self.append_input(
137
+ data.get("meta"),
138
+ data.get("ctx"),
139
+ data.get("flush", True),
140
+ data.get("append", False),
141
+ )
136
142
  elif name == RenderEvent.OUTPUT_APPEND:
137
- self.append_output(meta, ctx)
143
+ self.append_output(data.get("meta"), data.get("ctx"))
138
144
 
139
145
  elif name == RenderEvent.EXTRA_APPEND:
140
- self.append_extra(meta, ctx, footer)
146
+ self.append_extra(data.get("meta"), data.get("ctx"), data.get("footer", False))
141
147
  elif name == RenderEvent.EXTRA_END:
142
- self.end_extra(meta, ctx)
148
+ self.end_extra(data.get("meta"), data.get("ctx"))
143
149
 
144
150
  elif name == RenderEvent.LIVE_APPEND:
145
- self.append_live(meta, ctx, chunk, begin)
151
+ self.append_live(
152
+ data.get("meta"),
153
+ data.get("ctx"),
154
+ data.get("chunk", ""),
155
+ data.get("begin", False),
156
+ )
146
157
  elif name == RenderEvent.LIVE_CLEAR:
147
- self.clear_live(meta, ctx)
158
+ self.clear_live(data.get("meta"), data.get("ctx"))
148
159
 
149
160
  elif name == RenderEvent.ACTION_REGEN_SUBMIT:
150
- self.on_reply_submit(ctx)
161
+ self.on_reply_submit(data.get("ctx"))
151
162
  elif name == RenderEvent.ACTION_EDIT_SUBMIT:
152
- self.on_edit_submit(ctx)
153
-
154
- # kernel state changed
155
- elif name in [
156
- RenderEvent.STATE_IDLE,
157
- RenderEvent.STATE_BUSY,
158
- RenderEvent.STATE_ERROR,
159
- ]:
160
- meta = meta or self.window.core.ctx.get_current_meta()
163
+ self.on_edit_submit(data.get("ctx"))
164
+
165
+ elif name in self._STATE_EVENTS:
166
+ meta = data.get("meta") or self.window.core.ctx.get_current_meta()
161
167
  self.on_state_changed(name, meta)
162
168
 
163
- def on_state_changed(self, state: str, meta: Optional[CtxMeta] = None):
169
+ def on_state_changed(self, state: str, meta: Optional[CtxMeta] = None) -> None:
164
170
  """
165
171
  Handle state change event
166
172
 
@@ -169,7 +175,7 @@ class Render:
169
175
  """
170
176
  self.instance().state_changed(state, meta)
171
177
 
172
- def append_live(self, meta: CtxMeta, ctx: CtxItem, text_chunk: str, begin: bool = False):
178
+ def append_live(self, meta: CtxMeta, ctx: CtxItem, text_chunk: str, begin: bool = False) -> None:
173
179
  """
174
180
  Append live text chunk to output
175
181
 
@@ -179,9 +185,8 @@ class Render:
179
185
  :param begin: if it is the beginning of the stream
180
186
  """
181
187
  self.instance().append_live(meta, ctx, text_chunk, begin)
182
- self.update()
183
188
 
184
- def clear_live(self, meta: CtxMeta, ctx: CtxItem):
189
+ def clear_live(self, meta: CtxMeta, ctx: CtxItem) -> None:
185
190
  """
186
191
  Clear live output
187
192
 
@@ -200,12 +205,7 @@ class Render:
200
205
  """
201
206
  return self.instance().get_pid(meta)
202
207
 
203
- def begin(
204
- self,
205
- meta: CtxMeta,
206
- ctx: CtxItem,
207
- stream: bool = False
208
- ):
208
+ def begin(self, meta: CtxMeta, ctx: CtxItem, stream: bool = False) -> None:
209
209
  """
210
210
  Render begin
211
211
 
@@ -216,12 +216,7 @@ class Render:
216
216
  self.instance().begin(meta, ctx, stream)
217
217
  self.update()
218
218
 
219
- def end(
220
- self,
221
- meta: CtxMeta,
222
- ctx: CtxItem,
223
- stream: bool = False
224
- ):
219
+ def end(self, meta: CtxMeta, ctx: CtxItem, stream: bool = False) -> None:
225
220
  """
226
221
  Render end
227
222
 
@@ -232,15 +227,10 @@ class Render:
232
227
  self.instance().end(meta, ctx, stream)
233
228
  self.update()
234
229
 
235
- def end_extra(
236
- self,
237
- meta: CtxMeta,
238
- ctx: CtxItem,
239
- stream: bool = False
240
- ):
230
+ def end_extra(self, meta: CtxMeta, ctx: CtxItem, stream: bool = False) -> None:
241
231
  """
242
232
  Render end extra
243
-
233
+
244
234
  :param meta: context meta
245
235
  :param ctx: context item
246
236
  :param stream: True if it is a stream
@@ -248,38 +238,27 @@ class Render:
248
238
  self.instance().end_extra(meta, ctx, stream)
249
239
  self.update()
250
240
 
251
- def stream_begin(
252
- self,
253
- meta: CtxMeta,
254
- ctx: CtxItem
255
- ):
241
+ def stream_begin(self, meta: CtxMeta, ctx: CtxItem) -> None:
256
242
  """
257
243
  Render stream begin
258
-
244
+
259
245
  :param meta: context meta
260
246
  :param ctx: context item
261
247
  """
262
248
  self.instance().stream_begin(meta, ctx)
263
249
  self.update()
264
250
 
265
- def stream_end(
266
- self,
267
- meta: CtxMeta,
268
- ctx: CtxItem
269
- ):
251
+ def stream_end(self, meta: CtxMeta, ctx: CtxItem) -> None:
270
252
  """
271
253
  Render stream end
272
-
254
+
273
255
  :param meta: context meta
274
256
  :param ctx: context item
275
257
  """
276
258
  self.instance().stream_end(meta, ctx)
277
259
  self.update()
278
260
 
279
- def clear_output(
280
- self,
281
- meta: Optional[CtxMeta] = None
282
- ):
261
+ def clear_output(self, meta: Optional[CtxMeta] = None) -> None:
283
262
  """
284
263
  Clear current active output
285
264
 
@@ -288,14 +267,11 @@ class Render:
288
267
  self.instance().clear_output(meta) # TODO: get meta id on load
289
268
  self.update()
290
269
 
291
- def clear_input(self):
270
+ def clear_input(self) -> None:
292
271
  """Clear input"""
293
272
  self.instance().clear_input()
294
273
 
295
- def on_load(
296
- self,
297
- meta: Optional[CtxMeta] = None
298
- ):
274
+ def on_load(self, meta: Optional[CtxMeta] = None) -> None:
299
275
  """
300
276
  On load (meta)
301
277
 
@@ -305,10 +281,7 @@ class Render:
305
281
  self.update()
306
282
  self.window.controller.ui.tabs.update_tooltip(meta.name) # update tab tooltip
307
283
 
308
- def fresh(
309
- self,
310
- meta: Optional[CtxMeta] = None
311
- ):
284
+ def fresh(self, meta: Optional[CtxMeta] = None) -> None:
312
285
  """
313
286
  On load (meta)
314
287
 
@@ -316,10 +289,7 @@ class Render:
316
289
  """
317
290
  self.instance().fresh(meta)
318
291
 
319
- def reset(
320
- self,
321
- meta: Optional[CtxMeta] = None
322
- ):
292
+ def reset(self, meta: Optional[CtxMeta] = None) -> None:
323
293
  """
324
294
  Reset current meta
325
295
 
@@ -328,17 +298,12 @@ class Render:
328
298
  self.instance().reset(meta) # TODO: get meta id on load
329
299
  self.update()
330
300
 
331
- def reload(self):
301
+ def reload(self) -> None:
332
302
  """Reload current output"""
333
303
  self.instance().reload() # TODO: or all outputs?
334
304
  self.update()
335
305
 
336
- def append_context(
337
- self,
338
- meta: CtxMeta,
339
- items: List[CtxItem],
340
- clear: bool = True
341
- ):
306
+ def append_context(self, meta: CtxMeta, items: List[CtxItem], clear: bool = True) -> None:
342
307
  """
343
308
  Append all context to output
344
309
 
@@ -349,16 +314,10 @@ class Render:
349
314
  self.instance().append_context(meta, items, clear)
350
315
  self.update()
351
316
 
352
- def append_input(
353
- self,
354
- meta: CtxMeta,
355
- ctx: CtxItem,
356
- flush: bool = True,
357
- append: bool = False
358
- ):
317
+ def append_input(self, meta: CtxMeta, ctx: CtxItem, flush: bool = True, append: bool = False) -> None:
359
318
  """
360
319
  Append text input to output
361
-
320
+
362
321
  :param meta: context meta
363
322
  :param ctx: context item
364
323
  :param flush: True if flush output
@@ -367,29 +326,20 @@ class Render:
367
326
  self.instance().append_input(meta, ctx, flush=flush, append=append)
368
327
  self.update()
369
328
 
370
- def append_output(
371
- self,
372
- meta: CtxMeta,
373
- ctx: CtxItem
374
- ):
329
+ def append_output(self, meta: CtxMeta, ctx: CtxItem) -> None:
375
330
  """
376
331
  Append text output to output
377
-
332
+
378
333
  :param meta: context meta
379
334
  :param ctx: context item
380
335
  """
381
336
  self.instance().append_output(meta, ctx)
382
337
  self.update()
383
338
 
384
- def append_extra(
385
- self,
386
- meta: CtxMeta,
387
- ctx: CtxItem,
388
- footer: bool = False
389
- ):
339
+ def append_extra(self, meta: CtxMeta, ctx: CtxItem, footer: bool = False) -> None:
390
340
  """
391
341
  Append extra data (images, files, etc.) to output
392
-
342
+
393
343
  :param meta: context meta
394
344
  :param ctx: context item
395
345
  :param footer: True if it is a footer
@@ -397,39 +347,28 @@ class Render:
397
347
  self.instance().append_extra(meta, ctx, footer)
398
348
  self.update()
399
349
 
400
- def append_chunk(
401
- self,
402
- meta: CtxMeta,
403
- ctx: CtxItem,
404
- text_chunk: str,
405
- begin: bool = False
406
- ):
350
+ def append_chunk(self, meta: CtxMeta, ctx: CtxItem, text_chunk: str, begin: bool = False) -> None:
407
351
  """
408
352
  Append output stream chunk to output
409
-
353
+
410
354
  :param meta: context meta
411
355
  :param ctx: context item
412
356
  :param text_chunk: text chunk
413
357
  :param begin: if it is the beginning of the stream
414
358
  """
415
359
  self.instance().append_chunk(meta, ctx, text_chunk, begin)
416
- self.update()
417
360
 
418
- def next_chunk(
419
- self,
420
- meta: CtxMeta,
421
- ctx: CtxItem,
422
- ):
361
+ def next_chunk(self, meta: CtxMeta, ctx: CtxItem) -> None:
423
362
  """
424
363
  Flush current stream and start with new chunks
425
-
364
+
426
365
  :param meta: context meta
427
366
  :param ctx: context item
428
367
  """
429
368
  self.instance().next_chunk(meta, ctx)
430
369
  self.update()
431
370
 
432
- def on_enable_edit(self, live: bool = True):
371
+ def on_enable_edit(self, live: bool = True) -> None:
433
372
  """
434
373
  On enable edit icons - global
435
374
 
@@ -438,7 +377,7 @@ class Render:
438
377
  self.instance().on_enable_edit(live)
439
378
  self.update()
440
379
 
441
- def on_disable_edit(self, live: bool = True):
380
+ def on_disable_edit(self, live: bool = True) -> None:
442
381
  """
443
382
  On disable edit icons - global
444
383
 
@@ -447,7 +386,7 @@ class Render:
447
386
  self.instance().on_disable_edit(live)
448
387
  self.update()
449
388
 
450
- def on_enable_timestamp(self, live: bool = True):
389
+ def on_enable_timestamp(self, live: bool = True) -> None:
451
390
  """
452
391
  On enable timestamp - global
453
392
 
@@ -456,7 +395,7 @@ class Render:
456
395
  self.instance().on_enable_timestamp(live)
457
396
  self.update()
458
397
 
459
- def on_disable_timestamp(self, live: bool = True):
398
+ def on_disable_timestamp(self, live: bool = True) -> None:
460
399
  """
461
400
  On disable timestamp - global
462
401
 
@@ -465,7 +404,7 @@ class Render:
465
404
  self.instance().on_disable_timestamp(live)
466
405
  self.update()
467
406
 
468
- def remove_item(self, id: int):
407
+ def remove_item(self, id: int) -> None:
469
408
  """
470
409
  Remove item from output
471
410
 
@@ -474,7 +413,7 @@ class Render:
474
413
  self.instance().remove_item(id)
475
414
  self.update()
476
415
 
477
- def remove_items_from(self, id: int):
416
+ def remove_items_from(self, id: int) -> None:
478
417
  """
479
418
  Remove item from output
480
419
 
@@ -483,7 +422,7 @@ class Render:
483
422
  self.instance().remove_items_from(id)
484
423
  self.update()
485
424
 
486
- def on_edit_submit(self, ctx: CtxItem):
425
+ def on_edit_submit(self, ctx: CtxItem) -> None:
487
426
  """
488
427
  On edit submit
489
428
 
@@ -492,7 +431,7 @@ class Render:
492
431
  self.instance().on_edit_submit(ctx)
493
432
  self.update()
494
433
 
495
- def on_remove_submit(self, ctx: CtxItem):
434
+ def on_remove_submit(self, ctx: CtxItem) -> None:
496
435
  """
497
436
  On remove submit
498
437
 
@@ -501,7 +440,7 @@ class Render:
501
440
  self.instance().on_remove_submit(ctx)
502
441
  self.update()
503
442
 
504
- def on_reply_submit(self, ctx: CtxItem):
443
+ def on_reply_submit(self, ctx: CtxItem) -> None:
505
444
  """
506
445
  On regenerate submit
507
446
 
@@ -510,11 +449,7 @@ class Render:
510
449
  self.instance().on_reply_submit(ctx)
511
450
  self.update()
512
451
 
513
- def on_page_loaded(
514
- self,
515
- meta: CtxMeta,
516
- tab: Optional[Tab] = None
517
- ):
452
+ def on_page_loaded(self, meta: CtxMeta, tab: Optional[Tab] = None) -> None:
518
453
  """
519
454
  On page loaded callback
520
455
 
@@ -524,7 +459,7 @@ class Render:
524
459
  self.instance().on_page_loaded(meta, tab)
525
460
  self.update()
526
461
 
527
- def on_theme_change(self):
462
+ def on_theme_change(self) -> None:
528
463
  """On theme change - global"""
529
464
  if self.get_engine() == "web":
530
465
  self.web_renderer.on_theme_change()
@@ -540,7 +475,7 @@ class Render:
540
475
  """
541
476
  return self.instance().get_scroll_position()
542
477
 
543
- def set_scroll_position(self, position: int):
478
+ def set_scroll_position(self, position: int) -> None:
544
479
  """
545
480
  Set scroll position - active
546
481
 
@@ -549,26 +484,32 @@ class Render:
549
484
  self.instance().set_scroll_position(position)
550
485
  self.update()
551
486
 
552
- def update(self):
487
+ def update(self) -> None:
553
488
  """On update - active"""
554
- for pin in self.window.ui.nodes['output']:
555
- self.window.ui.nodes['output'][pin].on_update()
489
+ nodes = self.window.ui.nodes
490
+ outputs = nodes.get('output')
491
+ if not outputs:
492
+ return
493
+ for node in outputs.values():
494
+ node.on_update()
556
495
 
557
- def clear(self, meta: CtxMeta):
496
+ def clear(self, meta: CtxMeta) -> None:
558
497
  """
559
498
  Clear renderer
560
499
 
561
500
  :param meta: ctx meta instance
562
501
  """
563
- self.reset(meta)
564
- self.clear_output(meta)
502
+ inst = self.instance()
503
+ inst.reset(meta)
504
+ inst.clear_output(meta)
505
+ self.update()
565
506
 
566
- def clear_all(self):
507
+ def clear_all(self) -> None:
567
508
  """Clear all"""
568
509
  self.instance().clear_all()
569
510
  self.update()
570
511
 
571
- def remove_pid(self, pid: int):
512
+ def remove_pid(self, pid: int) -> None:
572
513
  """
573
514
  Remove PID from renderer
574
515
 
@@ -578,11 +519,7 @@ class Render:
578
519
  self.markdown_renderer.remove_pid(pid)
579
520
  self.web_renderer.remove_pid(pid)
580
521
 
581
- def tool_output_append(
582
- self,
583
- meta: CtxMeta,
584
- content: str
585
- ):
522
+ def tool_output_append(self, meta: CtxMeta, content: str) -> None:
586
523
  """
587
524
  Add tool output (append)
588
525
 
@@ -592,11 +529,7 @@ class Render:
592
529
  self.instance().tool_output_append(meta, content)
593
530
  self.update()
594
531
 
595
- def tool_output_update(
596
- self,
597
- meta: CtxMeta,
598
- content: str
599
- ):
532
+ def tool_output_update(self, meta: CtxMeta, content: str) -> None:
600
533
  """
601
534
  Replace tool output
602
535
 
@@ -606,7 +539,7 @@ class Render:
606
539
  self.instance().tool_output_update(meta, content)
607
540
  self.update()
608
541
 
609
- def tool_output_clear(self, meta: CtxMeta):
542
+ def tool_output_clear(self, meta: CtxMeta) -> None:
610
543
  """
611
544
  Clear tool output
612
545
 
@@ -615,7 +548,7 @@ class Render:
615
548
  self.instance().tool_output_clear(meta)
616
549
  self.update()
617
550
 
618
- def tool_output_begin(self, meta: CtxMeta):
551
+ def tool_output_begin(self, meta: CtxMeta) -> None:
619
552
  """
620
553
  Begin tool output
621
554
 
@@ -624,7 +557,7 @@ class Render:
624
557
  self.instance().tool_output_begin(meta)
625
558
  self.update()
626
559
 
627
- def tool_output_end(self):
560
+ def tool_output_end(self) -> None:
628
561
  """
629
562
  End tool output
630
563
 
@@ -641,32 +574,42 @@ class Render:
641
574
  """
642
575
  return self.engine
643
576
 
644
- def switch(self):
577
+ def switch(self) -> None:
645
578
  """
646
579
  Switch renderer (markdown/web <==> plain text) - active, TODO: remove from settings, leave only checkbox
647
580
  """
648
581
  plain = self.window.core.config.get('render.plain')
582
+ nodes = self.window.ui.nodes
649
583
  if plain:
650
584
  self.window.controller.theme.markdown.clear()
651
- self.window.ui.nodes['output.timestamp'].setVisible(True)
652
- for pid in self.window.ui.nodes['output_plain']:
653
- try:
654
- if self.window.ui.nodes['output_plain'][pid] is not None:
655
- self.window.ui.nodes['output'][pid].setVisible(False)
656
- self.window.ui.nodes['output_plain'][pid].setVisible(True)
657
- except Exception as e:
658
- pass
585
+ nodes['output.timestamp'].setVisible(True)
586
+ outputs = nodes.get('output', {})
587
+ outputs_plain = nodes.get('output_plain', {})
588
+ for pid, w_plain in outputs_plain.items():
589
+ w = outputs.get(pid)
590
+ if w and w_plain:
591
+ w.setVisible(False)
592
+ w_plain.setVisible(True)
659
593
  else:
660
- self.window.ui.nodes['output.timestamp'].setVisible(False)
661
- self.window.controller.ctx.refresh() # TODO: move to on_switch
594
+ nodes['output.timestamp'].setVisible(False)
662
595
  self.window.controller.theme.markdown.update(force=True)
663
- for pid in self.window.ui.nodes['output']:
664
- try:
665
- if self.window.ui.nodes['output'][pid] is not None:
666
- self.window.ui.nodes['output'][pid].setVisible(True)
667
- self.window.ui.nodes['output_plain'][pid].setVisible(False)
668
- except Exception as e:
669
- pass
596
+ outputs = nodes.get('output', {})
597
+ outputs_plain = nodes.get('output_plain', {})
598
+ for pid, w in outputs.items():
599
+ w_plain = outputs_plain.get(pid)
600
+ if w and w_plain:
601
+ w.setVisible(True)
602
+ w_plain.setVisible(False)
603
+
604
+ if plain:
605
+ self.renderer = self.plaintext_renderer
606
+ else:
607
+ if self.engine == "web":
608
+ self.renderer = self.web_renderer
609
+ else:
610
+ self.renderer = self.markdown_renderer
611
+
612
+ self.window.controller.ctx.refresh()
670
613
 
671
614
  def instance(self) -> BaseRenderer:
672
615
  """
@@ -674,7 +617,8 @@ class Render:
674
617
 
675
618
  :return: Renderer instance
676
619
  """
677
- # get selected renderer
620
+ if self.renderer:
621
+ return self.renderer
678
622
  if self.window.core.config.get('render.plain'):
679
623
  return self.plaintext_renderer
680
624
  else:
@@ -684,11 +628,7 @@ class Render:
684
628
  return self.markdown_renderer
685
629
 
686
630
  @Slot(str, str)
687
- def handle_save_as(
688
- self,
689
- text: str,
690
- type: str = 'txt'
691
- ):
631
+ def handle_save_as(self, text: str, type: str = 'txt') -> None:
692
632
  """
693
633
  Handle save as signal # TODO: move to another class
694
634
 
@@ -709,4 +649,4 @@ class Render:
709
649
 
710
650
  :param text: Text to read # TODO: move to another class
711
651
  """
712
- self.window.controller.audio.read_text(text)
652
+ self.window.controller.audio.read_text(text)