pygpt-net 2.6.55__py3-none-any.whl → 2.6.57__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 (218) hide show
  1. pygpt_net/CHANGELOG.txt +12 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +26 -22
  4. pygpt_net/config.py +44 -0
  5. pygpt_net/controller/audio/audio.py +0 -0
  6. pygpt_net/controller/calendar/calendar.py +0 -0
  7. pygpt_net/controller/calendar/note.py +0 -0
  8. pygpt_net/controller/chat/chat.py +0 -0
  9. pygpt_net/controller/chat/handler/openai_stream.py +2 -1
  10. pygpt_net/controller/chat/handler/worker.py +0 -0
  11. pygpt_net/controller/chat/remote_tools.py +5 -3
  12. pygpt_net/controller/chat/render.py +0 -0
  13. pygpt_net/controller/chat/text.py +0 -0
  14. pygpt_net/controller/ctx/common.py +0 -0
  15. pygpt_net/controller/debug/debug.py +26 -2
  16. pygpt_net/controller/debug/fixtures.py +1 -1
  17. pygpt_net/controller/dialogs/confirm.py +15 -1
  18. pygpt_net/controller/dialogs/debug.py +2 -0
  19. pygpt_net/controller/lang/mapping.py +0 -0
  20. pygpt_net/controller/launcher/launcher.py +0 -0
  21. pygpt_net/controller/mode/mode.py +0 -0
  22. pygpt_net/controller/presets/presets.py +0 -0
  23. pygpt_net/controller/realtime/realtime.py +0 -0
  24. pygpt_net/controller/theme/theme.py +0 -0
  25. pygpt_net/controller/ui/mode.py +5 -3
  26. pygpt_net/controller/ui/tabs.py +0 -0
  27. pygpt_net/core/agents/agents.py +3 -1
  28. pygpt_net/core/agents/custom.py +150 -0
  29. pygpt_net/core/agents/provider.py +0 -0
  30. pygpt_net/core/builder/__init__.py +12 -0
  31. pygpt_net/core/builder/graph.py +478 -0
  32. pygpt_net/core/calendar/calendar.py +0 -0
  33. pygpt_net/core/ctx/ctx.py +0 -0
  34. pygpt_net/core/ctx/output.py +0 -0
  35. pygpt_net/core/debug/agent.py +0 -0
  36. pygpt_net/core/debug/agent_builder.py +29 -0
  37. pygpt_net/core/debug/console/console.py +0 -0
  38. pygpt_net/core/debug/db.py +0 -0
  39. pygpt_net/core/debug/debug.py +0 -0
  40. pygpt_net/core/debug/events.py +0 -0
  41. pygpt_net/core/debug/indexes.py +0 -0
  42. pygpt_net/core/debug/kernel.py +0 -0
  43. pygpt_net/core/debug/tabs.py +0 -0
  44. pygpt_net/core/filesystem/filesystem.py +0 -0
  45. pygpt_net/core/fixtures/__init__ +0 -0
  46. pygpt_net/core/fixtures/stream/__init__.py +0 -0
  47. pygpt_net/core/fixtures/stream/generator.py +0 -0
  48. pygpt_net/core/models/models.py +2 -1
  49. pygpt_net/core/plugins/plugins.py +60 -0
  50. pygpt_net/core/render/plain/pid.py +0 -0
  51. pygpt_net/core/render/plain/renderer.py +26 -4
  52. pygpt_net/core/render/web/body.py +46 -4
  53. pygpt_net/core/render/web/debug.py +0 -0
  54. pygpt_net/core/render/web/helpers.py +0 -0
  55. pygpt_net/core/render/web/pid.py +0 -0
  56. pygpt_net/core/render/web/renderer.py +15 -20
  57. pygpt_net/core/tabs/tab.py +0 -0
  58. pygpt_net/core/tabs/tabs.py +0 -0
  59. pygpt_net/core/text/utils.py +0 -0
  60. pygpt_net/css.qrc +0 -0
  61. pygpt_net/css_rc.py +0 -0
  62. pygpt_net/data/config/config.json +8 -7
  63. pygpt_net/data/config/models.json +3 -3
  64. pygpt_net/data/config/settings.json +14 -0
  65. pygpt_net/data/css/web-blocks.css +9 -0
  66. pygpt_net/data/css/web-blocks.dark.css +6 -0
  67. pygpt_net/data/css/web-blocks.darkest.css +6 -0
  68. pygpt_net/data/css/web-chatgpt.css +14 -6
  69. pygpt_net/data/css/web-chatgpt.dark.css +6 -0
  70. pygpt_net/data/css/web-chatgpt.darkest.css +6 -0
  71. pygpt_net/data/css/web-chatgpt.light.css +6 -0
  72. pygpt_net/data/css/web-chatgpt_wide.css +14 -6
  73. pygpt_net/data/css/web-chatgpt_wide.dark.css +6 -0
  74. pygpt_net/data/css/web-chatgpt_wide.darkest.css +6 -0
  75. pygpt_net/data/css/web-chatgpt_wide.light.css +6 -0
  76. pygpt_net/data/fixtures/fake_stream.txt +14 -1
  77. pygpt_net/data/icons/case.svg +0 -0
  78. pygpt_net/data/icons/chat1.svg +0 -0
  79. pygpt_net/data/icons/chat2.svg +0 -0
  80. pygpt_net/data/icons/chat3.svg +0 -0
  81. pygpt_net/data/icons/chat4.svg +0 -0
  82. pygpt_net/data/icons/fit.svg +0 -0
  83. pygpt_net/data/icons/note1.svg +0 -0
  84. pygpt_net/data/icons/note2.svg +0 -0
  85. pygpt_net/data/icons/note3.svg +0 -0
  86. pygpt_net/data/icons/stt.svg +0 -0
  87. pygpt_net/data/icons/translate.svg +0 -0
  88. pygpt_net/data/icons/tts.svg +0 -0
  89. pygpt_net/data/icons/url.svg +0 -0
  90. pygpt_net/data/icons/vision.svg +0 -0
  91. pygpt_net/data/icons/web_off.svg +0 -0
  92. pygpt_net/data/icons/web_on.svg +0 -0
  93. pygpt_net/data/js/app/async.js +166 -0
  94. pygpt_net/data/js/app/bridge.js +88 -0
  95. pygpt_net/data/js/app/common.js +212 -0
  96. pygpt_net/data/js/app/config.js +223 -0
  97. pygpt_net/data/js/app/custom.js +961 -0
  98. pygpt_net/data/js/app/data.js +84 -0
  99. pygpt_net/data/js/app/dom.js +322 -0
  100. pygpt_net/data/js/app/events.js +400 -0
  101. pygpt_net/data/js/app/highlight.js +542 -0
  102. pygpt_net/data/js/app/logger.js +305 -0
  103. pygpt_net/data/js/app/markdown.js +1137 -0
  104. pygpt_net/data/js/app/math.js +167 -0
  105. pygpt_net/data/js/app/nodes.js +395 -0
  106. pygpt_net/data/js/app/queue.js +260 -0
  107. pygpt_net/data/js/app/raf.js +250 -0
  108. pygpt_net/data/js/app/runtime.js +582 -0
  109. pygpt_net/data/js/app/scroll.js +433 -0
  110. pygpt_net/data/js/app/stream.js +2708 -0
  111. pygpt_net/data/js/app/template.js +287 -0
  112. pygpt_net/data/js/app/tool.js +87 -0
  113. pygpt_net/data/js/app/ui.js +86 -0
  114. pygpt_net/data/js/app/user.js +380 -0
  115. pygpt_net/data/js/app/utils.js +64 -0
  116. pygpt_net/data/js/app.min.js +880 -0
  117. pygpt_net/data/js/markdown-it/markdown-it-katex.min.js +1 -1
  118. pygpt_net/data/js/markdown-it/markdown-it.min.js +0 -0
  119. pygpt_net/data/locale/locale.de.ini +3 -1
  120. pygpt_net/data/locale/locale.en.ini +8 -0
  121. pygpt_net/data/locale/locale.es.ini +2 -0
  122. pygpt_net/data/locale/locale.fr.ini +2 -0
  123. pygpt_net/data/locale/locale.it.ini +2 -0
  124. pygpt_net/data/locale/locale.pl.ini +3 -1
  125. pygpt_net/data/locale/locale.uk.ini +3 -1
  126. pygpt_net/data/locale/locale.zh.ini +2 -0
  127. pygpt_net/data/locale/plugin.osm.en.ini +24 -24
  128. pygpt_net/data/locale/plugin.wolfram.en.ini +9 -9
  129. pygpt_net/fonts.qrc +0 -0
  130. pygpt_net/fonts_rc.py +0 -0
  131. pygpt_net/icons.qrc +0 -0
  132. pygpt_net/icons_rc.py +0 -0
  133. pygpt_net/item/agent.py +62 -0
  134. pygpt_net/item/builder_layout.py +62 -0
  135. pygpt_net/js.qrc +24 -1
  136. pygpt_net/js_rc.py +51394 -33687
  137. pygpt_net/plugin/base/worker.py +0 -0
  138. pygpt_net/plugin/cmd_web/config.py +17 -17
  139. pygpt_net/plugin/cmd_web/worker.py +325 -171
  140. pygpt_net/plugin/mcp/__init__.py +0 -0
  141. pygpt_net/plugin/mcp/config.py +0 -0
  142. pygpt_net/plugin/mcp/plugin.py +0 -0
  143. pygpt_net/plugin/mcp/worker.py +0 -0
  144. pygpt_net/plugin/osm/__init__.py +0 -0
  145. pygpt_net/plugin/osm/config.py +0 -0
  146. pygpt_net/plugin/osm/plugin.py +0 -0
  147. pygpt_net/plugin/osm/worker.py +0 -0
  148. pygpt_net/plugin/wolfram/__init__.py +0 -0
  149. pygpt_net/plugin/wolfram/config.py +0 -0
  150. pygpt_net/plugin/wolfram/plugin.py +0 -0
  151. pygpt_net/plugin/wolfram/worker.py +0 -0
  152. pygpt_net/provider/api/anthropic/tools.py +0 -0
  153. pygpt_net/provider/api/google/__init__.py +0 -0
  154. pygpt_net/provider/api/google/video.py +0 -0
  155. pygpt_net/provider/api/openai/agents/experts.py +0 -0
  156. pygpt_net/provider/api/openai/agents/remote_tools.py +0 -0
  157. pygpt_net/provider/api/openai/remote_tools.py +0 -0
  158. pygpt_net/provider/api/openai/responses.py +0 -0
  159. pygpt_net/provider/api/x_ai/__init__.py +2 -0
  160. pygpt_net/provider/api/x_ai/remote.py +0 -0
  161. pygpt_net/provider/core/agent/__init__.py +10 -0
  162. pygpt_net/provider/core/agent/base.py +51 -0
  163. pygpt_net/provider/core/agent/json_file.py +200 -0
  164. pygpt_net/provider/core/config/patch.py +33 -0
  165. pygpt_net/provider/core/config/patches/__init__.py +0 -0
  166. pygpt_net/provider/core/config/patches/patch_before_2_6_42.py +1 -0
  167. pygpt_net/provider/core/ctx/db_sqlite/storage.py +0 -0
  168. pygpt_net/provider/core/model/patches/__init__.py +0 -0
  169. pygpt_net/provider/core/model/patches/patch_before_2_6_42.py +0 -0
  170. pygpt_net/provider/core/preset/patch.py +0 -0
  171. pygpt_net/provider/core/preset/patches/__init__.py +0 -0
  172. pygpt_net/provider/core/preset/patches/patch_before_2_6_42.py +0 -0
  173. pygpt_net/provider/llms/anthropic.py +4 -0
  174. pygpt_net/provider/llms/base.py +2 -0
  175. pygpt_net/provider/llms/deepseek_api.py +2 -0
  176. pygpt_net/provider/llms/google.py +2 -0
  177. pygpt_net/provider/llms/hugging_face_api.py +4 -0
  178. pygpt_net/provider/llms/hugging_face_embedding.py +0 -0
  179. pygpt_net/provider/llms/hugging_face_router.py +2 -0
  180. pygpt_net/provider/llms/local.py +0 -0
  181. pygpt_net/provider/llms/mistral.py +4 -0
  182. pygpt_net/provider/llms/open_router.py +0 -0
  183. pygpt_net/provider/llms/perplexity.py +2 -0
  184. pygpt_net/provider/llms/utils.py +0 -0
  185. pygpt_net/provider/llms/voyage.py +0 -0
  186. pygpt_net/provider/llms/x_ai.py +2 -0
  187. pygpt_net/tools/agent_builder/__init__.py +12 -0
  188. pygpt_net/tools/agent_builder/tool.py +292 -0
  189. pygpt_net/tools/agent_builder/ui/__init__.py +0 -0
  190. pygpt_net/tools/agent_builder/ui/dialogs.py +152 -0
  191. pygpt_net/tools/agent_builder/ui/list.py +228 -0
  192. pygpt_net/tools/code_interpreter/ui/html.py +0 -0
  193. pygpt_net/tools/code_interpreter/ui/widgets.py +0 -0
  194. pygpt_net/tools/html_canvas/tool.py +23 -6
  195. pygpt_net/tools/html_canvas/ui/widgets.py +224 -2
  196. pygpt_net/ui/layout/chat/chat.py +0 -0
  197. pygpt_net/ui/layout/chat/output.py +5 -5
  198. pygpt_net/ui/main.py +10 -9
  199. pygpt_net/ui/menu/debug.py +39 -1
  200. pygpt_net/ui/widget/builder/__init__.py +12 -0
  201. pygpt_net/ui/widget/builder/editor.py +2001 -0
  202. pygpt_net/ui/widget/dialog/base.py +4 -1
  203. pygpt_net/ui/widget/draw/painter.py +0 -0
  204. pygpt_net/ui/widget/element/labels.py +9 -4
  205. pygpt_net/ui/widget/lists/db.py +0 -0
  206. pygpt_net/ui/widget/lists/debug.py +0 -0
  207. pygpt_net/ui/widget/tabs/body.py +0 -0
  208. pygpt_net/ui/widget/textarea/html.py +1 -0
  209. pygpt_net/ui/widget/textarea/input.py +28 -10
  210. pygpt_net/ui/widget/textarea/output.py +21 -1
  211. pygpt_net/ui/widget/textarea/web.py +31 -3
  212. pygpt_net/utils.py +40 -0
  213. {pygpt_net-2.6.55.dist-info → pygpt_net-2.6.57.dist-info}/METADATA +16 -2
  214. {pygpt_net-2.6.55.dist-info → pygpt_net-2.6.57.dist-info}/RECORD +116 -77
  215. pygpt_net/data/js/app.js +0 -5869
  216. {pygpt_net-2.6.55.dist-info → pygpt_net-2.6.57.dist-info}/LICENSE +0 -0
  217. {pygpt_net-2.6.55.dist-info → pygpt_net-2.6.57.dist-info}/WHEEL +0 -0
  218. {pygpt_net-2.6.55.dist-info → pygpt_net-2.6.57.dist-info}/entry_points.txt +0 -0
@@ -383,12 +383,16 @@ class Renderer(BaseRenderer):
383
383
  :param meta: context meta
384
384
  """
385
385
  node = self.get_output_node(meta)
386
+ follow = getattr(node, "was_at_bottom", None)
387
+ follow = node.was_at_bottom() if callable(follow) else True
386
388
  cursor = node.textCursor()
387
389
  cursor.movePosition(QTextCursor.End)
388
390
  block_format = QTextBlockFormat()
389
391
  block_format.setIndent(0)
390
392
  cursor.insertBlock(block_format)
391
- node.setTextCursor(cursor)
393
+ if follow or (hasattr(node, "is_auto_scroll_enabled") and node.is_auto_scroll_enabled()):
394
+ node.setTextCursor(cursor)
395
+ node.ensureCursorVisible()
392
396
 
393
397
  def append_raw(
394
398
  self,
@@ -404,12 +408,16 @@ class Renderer(BaseRenderer):
404
408
  :param text: text to append
405
409
  """
406
410
  node = self.get_output_node(meta)
411
+ follow = getattr(node, "was_at_bottom", None)
412
+ follow = node.was_at_bottom() if callable(follow) else True
407
413
  cur = node.textCursor()
408
414
  cur.movePosition(QTextCursor.End)
409
415
  if not node.document().isEmpty():
410
416
  cur.insertText("\n\n")
411
417
  cur.insertText(text.strip())
412
- node.setTextCursor(cur)
418
+ if follow or (hasattr(node, "is_auto_scroll_enabled") and node.is_auto_scroll_enabled()):
419
+ node.setTextCursor(cur)
420
+ node.ensureCursorVisible()
413
421
 
414
422
  def append_chunk_start(self, meta: CtxMeta, ctx: CtxItem):
415
423
  """
@@ -419,9 +427,13 @@ class Renderer(BaseRenderer):
419
427
  :param ctx: context item
420
428
  """
421
429
  node = self.get_output_node(meta)
430
+ follow = getattr(node, "was_at_bottom", None)
431
+ follow = node.was_at_bottom() if callable(follow) else True
422
432
  cursor = node.textCursor()
423
433
  cursor.movePosition(QTextCursor.End)
424
- node.setTextCursor(cursor)
434
+ if follow or (hasattr(node, "is_auto_scroll_enabled") and node.is_auto_scroll_enabled()):
435
+ node.setTextCursor(cursor)
436
+ node.ensureCursorVisible()
425
437
 
426
438
  def append_context_item(
427
439
  self,
@@ -454,10 +466,14 @@ class Renderer(BaseRenderer):
454
466
  :param end: end of the line character
455
467
  """
456
468
  node = self.get_output_node(meta)
469
+ follow = getattr(node, "was_at_bottom", None)
470
+ follow = node.was_at_bottom() if callable(follow) else True
457
471
  cur = node.textCursor()
458
472
  cur.movePosition(QTextCursor.End)
459
473
  cur.insertText(f"{str(text)}{end}")
460
- node.setTextCursor(cur)
474
+ if follow or (hasattr(node, "is_auto_scroll_enabled") and node.is_auto_scroll_enabled()):
475
+ node.setTextCursor(cur)
476
+ node.ensureCursorVisible()
461
477
 
462
478
  def append_timestamp(
463
479
  self,
@@ -514,9 +530,15 @@ class Renderer(BaseRenderer):
514
530
  :param meta: context meta
515
531
  """
516
532
  node = self.get_output_node(meta)
533
+ was_bottom = getattr(node, "was_at_bottom", None)
534
+ was_bottom = node.was_at_bottom() if callable(was_bottom) else True
535
+ allow = was_bottom or (hasattr(node, "is_auto_scroll_enabled") and node.is_auto_scroll_enabled())
536
+ if not allow:
537
+ return
517
538
  cursor = node.textCursor()
518
539
  cursor.movePosition(QTextCursor.End)
519
540
  node.setTextCursor(cursor)
541
+ node.ensureCursorVisible()
520
542
 
521
543
  def is_timestamp_enabled(self) -> bool:
522
544
  """
@@ -72,12 +72,40 @@ class Body:
72
72
  // tips
73
73
  """
74
74
 
75
- _HTML_P6 = """
76
- </script>
77
- <script type="text/javascript" src="qrc:///js/app.js"></script>
75
+ _HTML_P6_DEV = """
76
+ </script>
77
+ <script type="text/javascript" src="qrc:///js/app-async.js"></script>
78
+ <script type="text/javascript" src="qrc:///js/app-bridge.js"></script>
79
+ <script type="text/javascript" src="qrc:///js/app-common.js"></script>
80
+ <script type="text/javascript" src="qrc:///js/app-config.js"></script>
81
+ <script type="text/javascript" src="qrc:///js/app-custom.js"></script>
82
+ <script type="text/javascript" src="qrc:///js/app-data.js"></script>
83
+ <script type="text/javascript" src="qrc:///js/app-dom.js"></script>
84
+ <script type="text/javascript" src="qrc:///js/app-events.js"></script>
85
+ <script type="text/javascript" src="qrc:///js/app-highlight.js"></script>
86
+ <script type="text/javascript" src="qrc:///js/app-logger.js"></script>
87
+ <script type="text/javascript" src="qrc:///js/app-markdown.js"></script>
88
+ <script type="text/javascript" src="qrc:///js/app-math.js"></script>
89
+ <script type="text/javascript" src="qrc:///js/app-nodes.js"></script>
90
+ <script type="text/javascript" src="qrc:///js/app-raf.js"></script>
91
+ <script type="text/javascript" src="qrc:///js/app-scroll.js"></script>
92
+ <script type="text/javascript" src="qrc:///js/app-stream.js"></script>
93
+ <script type="text/javascript" src="qrc:///js/app-queue.js"></script>
94
+ <script type="text/javascript" src="qrc:///js/app-template.js"></script>
95
+ <script type="text/javascript" src="qrc:///js/app-tool.js"></script>
96
+ <script type="text/javascript" src="qrc:///js/app-ui.js"></script>
97
+ <script type="text/javascript" src="qrc:///js/app-user.js"></script>
98
+ <script type="text/javascript" src="qrc:///js/app-utils.js"></script>
99
+ <script type="text/javascript" src="qrc:///js/app-runtime.js"></script>
78
100
  </head>
79
101
  <body """
80
102
 
103
+ _HTML_P6_PROD = """
104
+ </script>
105
+ <script type="text/javascript" src="qrc:///js/app.min.js"></script>
106
+ </head>
107
+ <body """
108
+
81
109
  _HTML_P7 = """>
82
110
  <div id="container">
83
111
  <div id="_nodes_" class="nodes empty_list"></div>
@@ -205,6 +233,16 @@ class Body:
205
233
  .msg {
206
234
  text-rendering: optimizeSpeed;
207
235
  }
236
+ pre > code,
237
+ .hl-tail,
238
+ .hl-frozen {
239
+ contain: layout paint;
240
+ content-visibility: auto;
241
+ backface-visibility: hidden;
242
+ contain-intrinsic-size: 1px 600px;
243
+ transform: translateZ(0);
244
+ filter: none !important;
245
+ }
208
246
  """
209
247
 
210
248
  def __init__(self, window=None):
@@ -681,6 +719,8 @@ class Body:
681
719
  attach_path = os.path.join(app_path, "data", "icons", "attachments.svg").replace("\\", "/")
682
720
  db_path = os.path.join(app_path, "data", "icons", "db.svg").replace("\\", "/")
683
721
 
722
+ done_path = os.path.join(app_path, "data", "icons", "done.svg").replace("\\", "/")
723
+
684
724
  icons_js = (
685
725
  f'window.ICON_EXPAND="file://{expand_path}";'
686
726
  f'window.ICON_COLLAPSE="file://{collapse_path}";'
@@ -691,6 +731,7 @@ class Body:
691
731
  f'window.ICON_URL="file://{url_path}";'
692
732
  f'window.ICON_ATTACHMENTS="file://{attach_path}";'
693
733
  f'window.ICON_DB="file://{db_path}";'
734
+ f'window.ICON_DONE="file://{done_path}";'
694
735
  )
695
736
 
696
737
  t_copy = trans('ctx.extra.copy_code')
@@ -724,6 +765,7 @@ class Body:
724
765
  )
725
766
 
726
767
  tips_js = f'window.TIPS={tips_json};'
768
+ app_env = os.environ.get("PYGPT_APP_ENV", "prod").lower()
727
769
 
728
770
  return ''.join((
729
771
  self._HTML_P0,
@@ -738,7 +780,7 @@ class Body:
738
780
  style_js,
739
781
  self._HTML_P5,
740
782
  tips_js,
741
- self._HTML_P6,
783
+ self._HTML_P6_DEV if app_env == "dev" else self._HTML_P6_PROD,
742
784
  classes_str,
743
785
  self._HTML_P7,
744
786
  ))
File without changes
File without changes
File without changes
@@ -182,6 +182,7 @@ class Renderer(BaseRenderer):
182
182
  self._stream_timer: dict[int, QTimer] = {}
183
183
  self._stream_header: dict[int, str] = {}
184
184
  self._stream_last_flush: dict[int, float] = {}
185
+ self._stream_last_cleanup: float = 0.0
185
186
 
186
187
  # Pid-related cached methods
187
188
  self._get_pid = None
@@ -496,6 +497,7 @@ class Renderer(BaseRenderer):
496
497
  Soft cleanup, called after each context is done.
497
498
  """
498
499
  try:
500
+ gc.collect()
499
501
  malloc_trim_linux()
500
502
  except Exception:
501
503
  pass
@@ -1248,7 +1250,10 @@ class Renderer(BaseRenderer):
1248
1250
  html = self.body.get_html(pid)
1249
1251
  node = self.get_output_node_by_pid(pid)
1250
1252
  if node is not None:
1251
- node.setHtml(html, baseUrl="file://")
1253
+ try:
1254
+ node.setHtml(html, baseUrl="file://")
1255
+ except Exception as e:
1256
+ print("[Renderer] flush error:", e)
1252
1257
 
1253
1258
  def fresh(self, meta: Optional[CtxMeta] = None, force: bool = False):
1254
1259
  """
@@ -1319,7 +1324,7 @@ class Renderer(BaseRenderer):
1319
1324
  :return: output node or None
1320
1325
  """
1321
1326
  if self._get_output_node_by_meta is None:
1322
- self._get_output_node_by_meta = self.window.core.ctx.output.get_output_node_by_meta
1327
+ self._get_output_node_by_meta = self.window.core.ctx.output.get_current
1323
1328
  return self._get_output_node_by_meta(meta)
1324
1329
 
1325
1330
  def get_output_node_by_pid(self, pid: Optional[int]) -> Optional[ChatWebOutput]:
@@ -1330,7 +1335,7 @@ class Renderer(BaseRenderer):
1330
1335
  :return: output node or None
1331
1336
  """
1332
1337
  if self._get_output_node_by_pid is None:
1333
- self._get_output_node_by_pid = self.window.core.ctx.output.get_output_node_by_pid
1338
+ self._get_output_node_by_pid = self.window.core.ctx.output.get_by_pid
1334
1339
  return self._get_output_node_by_pid(pid)
1335
1340
 
1336
1341
  def get_input_node(self) -> ChatInput:
@@ -1861,29 +1866,19 @@ class Renderer(BaseRenderer):
1861
1866
  data = buf.get_and_clear()
1862
1867
  name = self._stream_header.get(pid, "") or ""
1863
1868
 
1864
- try:
1865
- br = getattr(node.page(), "bridge", None)
1866
- if br is not None and hasattr(br, "chunk"):
1867
- br.chunk.emit(name, data, "text_delta")
1868
- else:
1869
- node.page().runJavaScript(
1870
- f"if (typeof window.appendStream !== 'undefined') appendStream({self.to_json(name)},{self.to_json(data)});"
1871
- )
1872
- except Exception:
1873
- try:
1874
- node.page().runJavaScript(
1875
- f"if (typeof window.appendStream !== 'undefined') appendStream({self.to_json(name)},{self.to_json(data)});"
1876
- )
1877
- except Exception:
1878
- pass
1869
+ node.page().bridge.chunk.emit(name, data, "text_delta")
1879
1870
 
1880
1871
  try:
1881
- if len(data) >= (256 * 1024):
1872
+ del data
1873
+ # auto GC cleanup after some time
1874
+ now = monotonic()
1875
+ last = self._stream_last_cleanup
1876
+ if now - last > 120.0:
1882
1877
  self.auto_cleanup_soft()
1878
+ self._stream_last_cleanup = now
1883
1879
  except Exception:
1884
1880
  pass
1885
1881
 
1886
- del data
1887
1882
  self._stream_last_flush[pid] = monotonic()
1888
1883
 
1889
1884
  def eval_js(self, script: str):
File without changes
File without changes
File without changes
pygpt_net/css.qrc CHANGED
File without changes
pygpt_net/css_rc.py CHANGED
File without changes
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.55",
4
- "app.version": "2.6.55",
5
- "updated_at": "2025-09-18T00:00:00"
3
+ "version": "2.6.57",
4
+ "app.version": "2.6.57",
5
+ "updated_at": "2025-09-22T00:00:00"
6
6
  },
7
7
  "access.audio.event.speech": false,
8
8
  "access.audio.event.speech.disabled": [],
@@ -96,6 +96,7 @@
96
96
  "api_native_google.use_vertex": false,
97
97
  "api_native_xai": true,
98
98
  "api_proxy": "",
99
+ "api_proxy.enabled": false,
99
100
  "api_use_responses": true,
100
101
  "api_use_responses_llama": true,
101
102
  "app.env": [
@@ -433,14 +434,14 @@
433
434
  "render.code_syntax": "github-dark",
434
435
  "render.code_syntax.disabled": false,
435
436
  "render.code_syntax.final_max_chars": 350000,
436
- "render.code_syntax.final_max_lines": 1500,
437
- "render.code_syntax.stream_max_lines": 1000,
438
- "render.code_syntax.stream_n_line": 10,
437
+ "render.code_syntax.final_max_lines": 3000,
438
+ "render.code_syntax.stream_max_lines": 100,
439
+ "render.code_syntax.stream_n_line": 5,
439
440
  "render.code_syntax.stream_n_chars": 1000,
440
441
  "render.engine": "web",
441
442
  "render.memory.limit": "2.5GB",
442
443
  "render.msg.user.collapse.px": 1500,
443
- "render.open_gl": false,
444
+ "render.open_gl": true,
444
445
  "render.plain": false,
445
446
  "send_clear": true,
446
447
  "send_mode": 2,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.6.55",
4
- "app.version": "2.6.55",
5
- "updated_at": "2025-09-18T00:00:00"
3
+ "version": "2.6.57",
4
+ "app.version": "2.6.57",
5
+ "updated_at": "2025-09-22T00:00:00"
6
6
  },
7
7
  "items": {
8
8
  "SpeakLeash/bielik-11b-v2.3-instruct:Q4_K_M": {
@@ -579,6 +579,20 @@
579
579
  "step": 1,
580
580
  "advanced": false
581
581
  },
582
+ "api_proxy.enabled": {
583
+ "section": "general",
584
+ "type": "bool",
585
+ "slider": false,
586
+ "label": "settings.api_proxy.enabled",
587
+ "description": "settings.api_proxy.enabled.desc",
588
+ "value": true,
589
+ "min": null,
590
+ "max": null,
591
+ "multiplier": null,
592
+ "step": null,
593
+ "secret": false,
594
+ "advanced": false
595
+ },
582
596
  "api_proxy": {
583
597
  "section": "general",
584
598
  "type": "text",
@@ -124,6 +124,14 @@ think {{
124
124
  .code-header-copy:hover img {{
125
125
  filter: brightness(130%);
126
126
  }}
127
+ .code-header-preview span {{
128
+ padding-left: 6px;
129
+ padding-right: 2px;
130
+ }}
131
+ .code-header-run span {{
132
+ padding-left: 2px;
133
+ padding-right: 2px;
134
+ }}
127
135
  .code-wrapper {{
128
136
  padding: 0px;
129
137
  margin: 0px;
@@ -150,6 +158,7 @@ think {{
150
158
  }}
151
159
  .action-icons a {{
152
160
  text-decoration: none;
161
+ transition: filter 0.3s ease;
153
162
  }}
154
163
  .action-icons a:hover {{
155
164
  filter: brightness(120%);
@@ -65,6 +65,12 @@ code {{
65
65
  .code-header-lang {{
66
66
  color: #686868;
67
67
  }}
68
+ .code-wrapper .code-header-action.code-header-copy:hover,
69
+ .code-wrapper .code-header-action.code-header-collapse:hover {{
70
+ transform: scale(1.06);
71
+ background: var(--copy-btn-bg-hover, rgb(0 0 0 / 76%));
72
+ border-color: var(--copy-btn-border, rgba(0, 0, 0, .08));
73
+ }}
68
74
  .action-icons a:hover {{
69
75
  filter: brightness(130%);
70
76
  }}
@@ -65,6 +65,12 @@ code {{
65
65
  .code-header-lang {{
66
66
  color: #686868;
67
67
  }}
68
+ .code-wrapper .code-header-action.code-header-copy:hover,
69
+ .code-wrapper .code-header-action.code-header-collapse:hover {{
70
+ transform: scale(1.06);
71
+ background: var(--copy-btn-bg-hover, rgb(0 0 0 / 76%));
72
+ border-color: var(--copy-btn-border, rgba(0, 0, 0, .08));
73
+ }}
68
74
  .action-icons a:hover {{
69
75
  filter: brightness(130%);
70
76
  }}
@@ -43,8 +43,8 @@ a:hover {{
43
43
  text-decoration: underline;
44
44
  }}
45
45
  p {{
46
- margin-top: 0px;
47
- margin-bottom:0px;
46
+ margin-top: 0.5rem;
47
+ margin-bottom: 0.5rem;
48
48
  }}
49
49
 
50
50
  /* lists, code */
@@ -99,7 +99,7 @@ think {{
99
99
  -moz-border-radius-topleft: .25rem;
100
100
  -moz-border-radius-topright: .25rem;
101
101
  border-top-left-radius: .25rem;
102
- border-top-right-radius: .25rem;
102
+ border-top-right-radius: 0;
103
103
  }}
104
104
  .code-header {{
105
105
  text-align: right;
@@ -122,22 +122,29 @@ think {{
122
122
  vertical-align: middle;
123
123
  padding-left: 5px;
124
124
  padding-right: 5px;
125
+ margin-top: -3px;
125
126
  }}
126
127
  .code-header-action span {{
127
128
  font-family: "Lato" !important;
128
129
  }}
129
130
  .code-header-action img {{
130
131
  vertical-align: middle;
131
- padding-right: 5px;
132
- padding-bottom: 3px;
133
132
  }}
134
- .code-header-action:hover, {{
133
+ .code-header-action:hover {{
135
134
  text-decoration: none;
136
135
  cursor: pointer;
137
136
  }}
138
137
  .code-header-action:hover img {{
139
138
  filter: brightness(130%);
140
139
  }}
140
+ .code-header-preview span {{
141
+ padding-left: 6px;
142
+ padding-right: 2px;
143
+ }}
144
+ .code-header-run span {{
145
+ padding-left: 2px;
146
+ padding-right: 2px;
147
+ }}
141
148
  .code-wrapper {{
142
149
  padding: 0px;
143
150
  margin: 0px;
@@ -167,6 +174,7 @@ think {{
167
174
  }}
168
175
  .action-icons a {{
169
176
  text-decoration: none;
177
+ transition: filter 0.3s ease;
170
178
  }}
171
179
  .action-icons a:hover {{
172
180
  filter: brightness(120%);
@@ -65,6 +65,12 @@ code {{
65
65
  .code-header-lang {{
66
66
  color: #686868;
67
67
  }}
68
+ .code-wrapper .code-header-action.code-header-copy:hover,
69
+ .code-wrapper .code-header-action.code-header-collapse:hover {{
70
+ transform: scale(1.06);
71
+ background: var(--copy-btn-bg-hover, rgb(0 0 0 / 76%));
72
+ border-color: var(--copy-btn-border, rgba(0, 0, 0, .08));
73
+ }}
68
74
  .action-icons a:hover {{
69
75
  filter: brightness(130%);
70
76
  }}
@@ -65,6 +65,12 @@ code {{
65
65
  .code-header-lang {{
66
66
  color: #686868;
67
67
  }}
68
+ .code-wrapper .code-header-action.code-header-copy:hover,
69
+ .code-wrapper .code-header-action.code-header-collapse:hover {{
70
+ transform: scale(1.06);
71
+ background: var(--copy-btn-bg-hover, rgb(0 0 0 / 76%));
72
+ border-color: var(--copy-btn-border, rgba(0, 0, 0, .08));
73
+ }}
68
74
  .action-icons a:hover {{
69
75
  filter: brightness(130%);
70
76
  }}
@@ -66,6 +66,12 @@ code {{
66
66
  .code-header-lang {{
67
67
  color: #5c5c5c;
68
68
  }}
69
+ .code-wrapper .code-header-action.code-header-copy:hover,
70
+ .code-wrapper .code-header-action.code-header-collapse:hover {{
71
+ transform: scale(1.06);
72
+ background: var(--copy-btn-bg-hover, rgb(225 225 225 / 76%));
73
+ border-color: var(--copy-btn-border, rgba(0, 0, 0, .08));
74
+ }}
69
75
  .msg-user {{
70
76
  background-color: #f3f3f3;
71
77
  color: #000;
@@ -43,8 +43,8 @@ a:hover {{
43
43
  text-decoration: underline;
44
44
  }}
45
45
  p {{
46
- margin-top: 0px;
47
- margin-bottom:0px;
46
+ margin-top: 0.5rem;
47
+ margin-bottom: 0.5rem;
48
48
  }}
49
49
  /* lists, code */
50
50
  ol,
@@ -101,7 +101,7 @@ think {{
101
101
  -moz-border-radius-topleft: .25rem;
102
102
  -moz-border-radius-topright: .25rem;
103
103
  border-top-left-radius: .25rem;
104
- border-top-right-radius: .25rem;
104
+ border-top-right-radius: 0;
105
105
  }}
106
106
  .code-header {{
107
107
  text-align: right;
@@ -124,19 +124,26 @@ think {{
124
124
  vertical-align: middle;
125
125
  padding-left: 5px;
126
126
  padding-right: 5px;
127
+ margin-top: -3px;
127
128
  }}
128
129
  .code-header-action img {{
129
130
  vertical-align: middle;
130
- padding-right: 5px;
131
- padding-bottom: 3px;
132
131
  }}
133
- .code-header-action:hover, {{
132
+ .code-header-action:hover {{
134
133
  text-decoration: none;
135
134
  cursor: pointer;
136
135
  }}
137
136
  .code-header-action:hover img {{
138
137
  filter: brightness(130%);
139
138
  }}
139
+ .code-header-preview span {{
140
+ padding-left: 6px;
141
+ padding-right: 2px;
142
+ }}
143
+ .code-header-run span {{
144
+ padding-left: 2px;
145
+ padding-right: 2px;
146
+ }}
140
147
  .code-wrapper {{
141
148
  padding: 0px;
142
149
  margin: 0px;
@@ -166,6 +173,7 @@ think {{
166
173
  }}
167
174
  .action-icons a {{
168
175
  text-decoration: none;
176
+ transition: filter 0.3s ease;
169
177
  }}
170
178
  .action-icons a:hover {{
171
179
  filter: brightness(120%);
@@ -65,6 +65,12 @@ code {{
65
65
  .code-header-lang {{
66
66
  color: #686868;
67
67
  }}
68
+ .code-wrapper .code-header-action.code-header-copy:hover,
69
+ .code-wrapper .code-header-action.code-header-collapse:hover {{
70
+ transform: scale(1.06);
71
+ background: var(--copy-btn-bg-hover, rgb(0 0 0 / 76%));
72
+ border-color: var(--copy-btn-border, rgba(0, 0, 0, .08));
73
+ }}
68
74
  .action-icons a:hover {{
69
75
  filter: brightness(130%);
70
76
  }}
@@ -65,6 +65,12 @@ code {{
65
65
  .code-header-lang {{
66
66
  color: #686868;
67
67
  }}
68
+ .code-wrapper .code-header-action.code-header-copy:hover,
69
+ .code-wrapper .code-header-action.code-header-collapse:hover {{
70
+ transform: scale(1.06);
71
+ background: var(--copy-btn-bg-hover, rgb(0 0 0 / 76%));
72
+ border-color: var(--copy-btn-border, rgba(0, 0, 0, .08));
73
+ }}
68
74
  .action-icons a:hover {{
69
75
  filter: brightness(130%);
70
76
  }}
@@ -67,6 +67,12 @@ code {{
67
67
  .code-header-lang {{
68
68
  color: #5c5c5c;
69
69
  }}
70
+ .code-wrapper .code-header-action.code-header-copy:hover,
71
+ .code-wrapper .code-header-action.code-header-collapse:hover {{
72
+ transform: scale(1.06);
73
+ background: var(--copy-btn-bg-hover, rgb(225 225 225 / 76%));
74
+ border-color: var(--copy-btn-border, rgba(0, 0, 0, .08));
75
+ }}
70
76
  .name-bot::before {{
71
77
  background-color: #6b6b6b;
72
78
  }}
@@ -1,8 +1,21 @@
1
1
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent lobortis lorem sapien, eu viverra tellus auctor nec. Nulla aliquet iaculis tellus, in tempus massa eleifend a. Vestibulum viverra, massa nec aliquet ultrices, felis libero eleifend est, eu elementum sapien libero vitae lectus. Quisque rhoncus mollis felis, sed finibus ex pharetra ultricies. Praesent viverra nulla id congue ullamcorper.
2
2
 
3
+ # Header 1
4
+
5
+ ## Header 2
6
+
7
+ **Lorem** ipsum.
8
+
9
+ - list1
10
+ - list2
11
+ - list3
12
+
13
+ `var a = 1;`
14
+
3
15
  <think>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent lobortis lorem sapien, eu viverra tellus auctor nec. Nulla aliquet iaculis tellus, in tempus massa eleifend a. Vestibulum viverra, massa nec aliquet ultrices, felis libero eleifend est, eu elementum sapien libero vitae lectus. Quisque rhoncus mollis felis, sed finibus ex pharetra ultricies. Praesent viverra nulla id congue ullamcorper.</think>
4
16
 
5
- <execute>a = 1
17
+ <execute>
18
+ a = 1
6
19
  b = 2
7
20
  c = a + b
8
21
  print(c)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes