pygpt-net 2.7.4__py3-none-any.whl → 2.7.5__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 (133) hide show
  1. pygpt_net/CHANGELOG.txt +7 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app_core.py +4 -2
  4. pygpt_net/controller/__init__.py +5 -1
  5. pygpt_net/controller/assistant/assistant.py +1 -4
  6. pygpt_net/controller/assistant/batch.py +5 -504
  7. pygpt_net/controller/assistant/editor.py +5 -5
  8. pygpt_net/controller/assistant/files.py +16 -16
  9. pygpt_net/controller/chat/handler/google_stream.py +307 -1
  10. pygpt_net/controller/chat/handler/worker.py +8 -1
  11. pygpt_net/controller/chat/image.py +2 -2
  12. pygpt_net/controller/dialogs/confirm.py +73 -101
  13. pygpt_net/controller/lang/mapping.py +9 -9
  14. pygpt_net/controller/painter/capture.py +50 -1
  15. pygpt_net/controller/presets/presets.py +2 -1
  16. pygpt_net/controller/remote_store/__init__.py +12 -0
  17. pygpt_net/{provider/core/assistant_file/db_sqlite → controller/remote_store/google}/__init__.py +2 -2
  18. pygpt_net/controller/remote_store/google/batch.py +402 -0
  19. pygpt_net/controller/remote_store/google/store.py +615 -0
  20. pygpt_net/controller/remote_store/openai/__init__.py +12 -0
  21. pygpt_net/controller/remote_store/openai/batch.py +524 -0
  22. pygpt_net/controller/{assistant → remote_store/openai}/store.py +63 -60
  23. pygpt_net/controller/remote_store/remote_store.py +35 -0
  24. pygpt_net/controller/ui/ui.py +20 -1
  25. pygpt_net/core/assistants/assistants.py +3 -15
  26. pygpt_net/core/db/database.py +5 -3
  27. pygpt_net/core/locale/placeholder.py +35 -0
  28. pygpt_net/core/remote_store/__init__.py +12 -0
  29. pygpt_net/core/remote_store/google/__init__.py +11 -0
  30. pygpt_net/core/remote_store/google/files.py +224 -0
  31. pygpt_net/core/remote_store/google/store.py +248 -0
  32. pygpt_net/core/remote_store/openai/__init__.py +11 -0
  33. pygpt_net/core/{assistants → remote_store/openai}/files.py +26 -19
  34. pygpt_net/core/{assistants → remote_store/openai}/store.py +32 -15
  35. pygpt_net/core/remote_store/remote_store.py +24 -0
  36. pygpt_net/data/config/config.json +8 -4
  37. pygpt_net/data/config/models.json +77 -3
  38. pygpt_net/data/config/settings.json +45 -0
  39. pygpt_net/data/locale/locale.de.ini +41 -41
  40. pygpt_net/data/locale/locale.en.ini +53 -43
  41. pygpt_net/data/locale/locale.es.ini +41 -41
  42. pygpt_net/data/locale/locale.fr.ini +41 -41
  43. pygpt_net/data/locale/locale.it.ini +41 -41
  44. pygpt_net/data/locale/locale.pl.ini +42 -42
  45. pygpt_net/data/locale/locale.uk.ini +41 -41
  46. pygpt_net/data/locale/locale.zh.ini +41 -41
  47. pygpt_net/data/locale/plugin.cmd_history.de.ini +1 -1
  48. pygpt_net/data/locale/plugin.cmd_history.en.ini +1 -1
  49. pygpt_net/data/locale/plugin.cmd_history.es.ini +1 -1
  50. pygpt_net/data/locale/plugin.cmd_history.fr.ini +1 -1
  51. pygpt_net/data/locale/plugin.cmd_history.it.ini +1 -1
  52. pygpt_net/data/locale/plugin.cmd_history.pl.ini +1 -1
  53. pygpt_net/data/locale/plugin.cmd_history.uk.ini +1 -1
  54. pygpt_net/data/locale/plugin.cmd_history.zh.ini +1 -1
  55. pygpt_net/data/locale/plugin.cmd_mouse_control.en.ini +14 -0
  56. pygpt_net/data/locale/plugin.cmd_web.de.ini +1 -1
  57. pygpt_net/data/locale/plugin.cmd_web.en.ini +1 -1
  58. pygpt_net/data/locale/plugin.cmd_web.es.ini +1 -1
  59. pygpt_net/data/locale/plugin.cmd_web.fr.ini +1 -1
  60. pygpt_net/data/locale/plugin.cmd_web.it.ini +1 -1
  61. pygpt_net/data/locale/plugin.cmd_web.pl.ini +1 -1
  62. pygpt_net/data/locale/plugin.cmd_web.uk.ini +1 -1
  63. pygpt_net/data/locale/plugin.cmd_web.zh.ini +1 -1
  64. pygpt_net/data/locale/plugin.idx_llama_index.de.ini +2 -2
  65. pygpt_net/data/locale/plugin.idx_llama_index.en.ini +2 -2
  66. pygpt_net/data/locale/plugin.idx_llama_index.es.ini +2 -2
  67. pygpt_net/data/locale/plugin.idx_llama_index.fr.ini +2 -2
  68. pygpt_net/data/locale/plugin.idx_llama_index.it.ini +2 -2
  69. pygpt_net/data/locale/plugin.idx_llama_index.pl.ini +2 -2
  70. pygpt_net/data/locale/plugin.idx_llama_index.uk.ini +2 -2
  71. pygpt_net/data/locale/plugin.idx_llama_index.zh.ini +2 -2
  72. pygpt_net/item/assistant.py +1 -211
  73. pygpt_net/item/ctx.py +3 -1
  74. pygpt_net/item/store.py +238 -0
  75. pygpt_net/migrations/Version20260102190000.py +35 -0
  76. pygpt_net/migrations/__init__.py +3 -1
  77. pygpt_net/plugin/cmd_mouse_control/config.py +470 -1
  78. pygpt_net/plugin/cmd_mouse_control/plugin.py +488 -22
  79. pygpt_net/plugin/cmd_mouse_control/worker.py +464 -87
  80. pygpt_net/plugin/cmd_mouse_control/worker_sandbox.py +729 -0
  81. pygpt_net/plugin/idx_llama_index/config.py +2 -2
  82. pygpt_net/provider/api/google/__init__.py +16 -54
  83. pygpt_net/provider/api/google/chat.py +546 -129
  84. pygpt_net/provider/api/google/computer.py +190 -0
  85. pygpt_net/provider/api/google/realtime/realtime.py +2 -2
  86. pygpt_net/provider/api/google/remote_tools.py +93 -0
  87. pygpt_net/provider/api/google/store.py +546 -0
  88. pygpt_net/provider/api/google/worker/__init__.py +0 -0
  89. pygpt_net/provider/api/google/worker/importer.py +392 -0
  90. pygpt_net/provider/api/openai/computer.py +10 -1
  91. pygpt_net/provider/api/openai/store.py +6 -6
  92. pygpt_net/provider/api/openai/worker/importer.py +24 -24
  93. pygpt_net/provider/core/config/patch.py +16 -1
  94. pygpt_net/provider/core/config/patches/patch_before_2_6_42.py +3 -3
  95. pygpt_net/provider/core/model/patch.py +17 -3
  96. pygpt_net/provider/core/preset/json_file.py +13 -7
  97. pygpt_net/provider/core/{assistant_file → remote_file}/__init__.py +1 -1
  98. pygpt_net/provider/core/{assistant_file → remote_file}/base.py +9 -9
  99. pygpt_net/provider/core/remote_file/db_sqlite/__init__.py +12 -0
  100. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/patch.py +1 -1
  101. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/provider.py +23 -20
  102. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/storage.py +35 -27
  103. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/utils.py +5 -4
  104. pygpt_net/provider/core/{assistant_store → remote_store}/__init__.py +1 -1
  105. pygpt_net/provider/core/{assistant_store → remote_store}/base.py +10 -10
  106. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/__init__.py +1 -1
  107. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/patch.py +1 -1
  108. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/provider.py +16 -15
  109. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/storage.py +30 -23
  110. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/utils.py +5 -4
  111. pygpt_net/provider/core/{assistant_store → remote_store}/json_file.py +9 -9
  112. pygpt_net/provider/llms/google.py +2 -2
  113. pygpt_net/ui/base/config_dialog.py +3 -2
  114. pygpt_net/ui/dialog/assistant.py +3 -3
  115. pygpt_net/ui/dialog/plugins.py +3 -1
  116. pygpt_net/ui/dialog/remote_store_google.py +539 -0
  117. pygpt_net/ui/dialog/{assistant_store.py → remote_store_openai.py} +95 -95
  118. pygpt_net/ui/dialogs.py +5 -3
  119. pygpt_net/ui/layout/chat/attachments_uploaded.py +3 -3
  120. pygpt_net/ui/layout/toolbox/computer_env.py +26 -8
  121. pygpt_net/ui/menu/tools.py +13 -5
  122. pygpt_net/ui/widget/dialog/remote_store_google.py +56 -0
  123. pygpt_net/ui/widget/dialog/{assistant_store.py → remote_store_openai.py} +9 -9
  124. pygpt_net/ui/widget/element/button.py +4 -4
  125. pygpt_net/ui/widget/lists/remote_store_google.py +248 -0
  126. pygpt_net/ui/widget/lists/{assistant_store.py → remote_store_openai.py} +21 -21
  127. pygpt_net/ui/widget/option/checkbox_list.py +47 -9
  128. pygpt_net/ui/widget/option/combo.py +39 -3
  129. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.5.dist-info}/METADATA +33 -2
  130. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.5.dist-info}/RECORD +133 -108
  131. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.5.dist-info}/LICENSE +0 -0
  132. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.5.dist-info}/WHEEL +0 -0
  133. {pygpt_net-2.7.4.dist-info → pygpt_net-2.7.5.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.09.19 00:00:00 #
9
+ # Updated Date: 2026.01.02 20:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Any, Optional
@@ -80,19 +80,19 @@ class Confirm:
80
80
 
81
81
  # interpreter
82
82
  elif type == 'interpreter.clear':
83
- self.window.tools.get("interpreter").clear(force=True)
83
+ self.window.tools.get("interpreter").clear(True)
84
84
 
85
85
  # html canvas
86
86
  elif type == 'html_canvas.clear':
87
- self.window.tools.get("html_canvas").clear(force=True)
87
+ self.window.tools.get("html_canvas").clear(True)
88
88
 
89
89
  # translator
90
90
  elif type == 'translator.clear':
91
- self.window.tools.get("translator").clear(force=True)
91
+ self.window.tools.get("translator").clear(True)
92
92
  elif type == 'translator.clear.left':
93
- self.window.tools.get("translator").clear_left(force=True)
93
+ self.window.tools.get("translator").clear_left(True)
94
94
  elif type == 'translator.clear.right':
95
- self.window.tools.get("translator").clear_right(force=True)
95
+ self.window.tools.get("translator").clear_right(True)
96
96
 
97
97
  elif type == "preset.avatar.delete":
98
98
  self.window.controller.presets.editor.remove_avatar(True)
@@ -190,38 +190,66 @@ class Confirm:
190
190
  self.window.controller.assistant.delete(id, True)
191
191
  elif type == 'assistant.import':
192
192
  self.window.controller.assistant.batch.import_assistants(True)
193
- elif type == 'assistant.files.import.all':
194
- self.window.controller.assistant.batch.import_files(True)
195
- elif type == 'assistant.files.import.store':
196
- self.window.controller.assistant.batch.import_store_files(id, True) # by store_id
197
- elif type == 'assistant.files.truncate':
198
- self.window.controller.assistant.batch.truncate_files(True)
199
- elif type == 'assistant.files.truncate.store':
200
- self.window.controller.assistant.batch.truncate_store_files(id, True) # by store_id
201
- elif type == 'assistant.files.clear.all':
202
- self.window.controller.assistant.batch.clear_files(True)
203
- elif type == 'assistant.files.clear.store':
204
- self.window.controller.assistant.batch.clear_store_files(id, True) # by store_id
205
- elif type == 'assistant.files.upload':
206
- self.window.controller.assistant.batch.upload(True)
207
- elif type == 'assistant.file.delete':
208
- self.window.controller.assistant.store.delete_file_by_idx(id, True)
209
193
  elif type == 'assistant.functions.import':
210
194
  self.window.controller.assistant.editor.import_functions(True)
211
195
  elif type == 'assistant.functions.clear':
212
196
  self.window.controller.assistant.editor.clear_functions(True)
213
197
 
214
- # assistants vector stores
215
- elif type == 'assistant.store.delete':
216
- self.window.controller.assistant.store.delete(id, True) # by store_id
217
- elif type == 'assistant.store.import':
218
- self.window.controller.assistant.batch.import_stores(True)
219
- elif type == 'assistant.store.truncate':
220
- self.window.controller.assistant.batch.truncate_stores(True)
221
- elif type == 'assistant.store.clear':
222
- self.window.controller.assistant.batch.clear_stores(True)
223
- elif type == 'assistant.store.refresh':
224
- self.window.controller.assistant.batch.refresh_stores(True)
198
+ # OpenAI vector stores
199
+ elif type == 'remote_store.openai.file.delete':
200
+ self.window.controller.remote_store.openai.delete_file_by_idx(id, True)
201
+ elif type == 'remote_store.openai.delete':
202
+ self.window.controller.remote_store.openai.delete(id, True)
203
+ elif type == 'remote_store.openai.import':
204
+ self.window.controller.remote_store.openai.batch.import_stores(True)
205
+ elif type == 'remote_store.openai.truncate':
206
+ self.window.controller.remote_store.openai.batch.truncate_stores(True)
207
+ elif type == 'remote_store.openai.clear':
208
+ self.window.controller.remote_store.openai.batch.clear_stores(True)
209
+ elif type == 'remote_store.openai.refresh':
210
+ self.window.controller.remote_store.openai.batch.refresh_stores(True)
211
+ elif type == 'remote_store.openai.files.import.all':
212
+ self.window.controller.remote_store.openai.batch.import_files(True)
213
+ elif type == 'remote_store.openai.files.import.store':
214
+ self.window.controller.remote_store.openai.batch.import_store_files(id, True)
215
+ elif type == 'remote_store.openai.files.truncate':
216
+ self.window.controller.remote_store.openai.batch.truncate_files(True)
217
+ elif type == 'remote_store.openai.files.truncate.store':
218
+ self.window.controller.remote_store.openai.batch.truncate_store_files(id, True)
219
+ elif type == 'remote_store.openai.files.clear.all':
220
+ self.window.controller.remote_store.openai.batch.clear_files(True)
221
+ elif type == 'remote_store.openai.files.clear.store':
222
+ self.window.controller.remote_store.openai.batch.clear_store_files(id, True)
223
+ elif type == 'remote_store.openai.files.upload':
224
+ self.window.controller.remote_store.openai.batch.upload(True)
225
+
226
+ # Google (Gemini) File Search stores
227
+ elif type == 'remote_store.google.file.delete':
228
+ self.window.controller.remote_store.google.delete_file_by_idx(id, True)
229
+ elif type == 'remote_store.google.delete':
230
+ self.window.controller.remote_store.google.delete(id, True)
231
+ elif type == 'remote_store.google.import':
232
+ self.window.controller.remote_store.google.batch.import_stores(True)
233
+ elif type == 'remote_store.google.truncate':
234
+ self.window.controller.remote_store.google.batch.truncate_stores(True)
235
+ elif type == 'remote_store.google.clear':
236
+ self.window.controller.remote_store.google.batch.clear_stores(True)
237
+ elif type == 'remote_store.google.refresh':
238
+ self.window.controller.remote_store.google.batch.refresh_stores(True)
239
+ elif type == 'remote_store.google.files.import.all':
240
+ self.window.controller.remote_store.google.batch.import_files(True)
241
+ elif type == 'remote_store.google.files.import.store':
242
+ self.window.controller.remote_store.google.batch.import_store_files(id, True)
243
+ elif type == 'remote_store.google.files.truncate':
244
+ self.window.controller.remote_store.google.batch.truncate_files(True)
245
+ elif type == 'remote_store.google.files.truncate.store':
246
+ self.window.controller.remote_store.google.batch.truncate_store_files(id, True)
247
+ elif type == 'remote_store.google.files.clear.all':
248
+ self.window.controller.remote_store.google.batch.clear_files(True)
249
+ elif type == 'remote_store.google.files.clear.store':
250
+ self.window.controller.remote_store.google.batch.clear_store_files(id, True)
251
+ elif type == 'remote_store.google.files.upload':
252
+ self.window.controller.remote_store.google.batch.upload(True)
225
253
 
226
254
  # settings
227
255
  elif type == 'settings.defaults.user':
@@ -267,7 +295,7 @@ class Confirm:
267
295
  elif type == 'idx.index.ctx.remove':
268
296
  self.window.controller.idx.indexer.index_ctx_meta_remove(idx="", meta_id=id, force=True) # id = ctx meta id
269
297
  elif type == 'idx.index.db':
270
- self.window.controller.idx.indexer.index_ctx_meta_confirm(id) # id = ctx_id
298
+ self.window.controller.idx.indexer.index_ctx_meta_confirm(id)
271
299
  elif type == 'idx.index.db.all':
272
300
  self.window.controller.idx.indexer.index_ctx_from_ts_confirm(id)
273
301
  elif type == 'idx.clear':
@@ -291,18 +319,11 @@ class Confirm:
291
319
  elif type == 'agent.builder.agent.clear':
292
320
  self.window.tools.get("agent_builder").clear(True)
293
321
 
294
- def dismiss(
295
- self,
296
- type: str,
297
- id: Any
298
- ):
322
+ def dismiss(self, type: str, id: Any):
299
323
  """
300
324
  Confirm dialog dismiss
301
-
302
- :param type: dialog type
303
- :param id: dialog object id
304
325
  """
305
- # editor
326
+ # Keep original logic...
306
327
  if type == 'editor.changed.clear':
307
328
  self.window.tools.get("editor").clear(id=id, force=True)
308
329
  elif type == 'editor.changed.open':
@@ -324,115 +345,66 @@ class Confirm:
324
345
 
325
346
  self.window.ui.dialog['confirm'].close()
326
347
 
327
- def accept_rename(
328
- self,
329
- type: str,
330
- id: Any,
331
- name: str
332
- ):
348
+ def accept_rename(self, type: str, id: Any, name: str):
333
349
  """
334
350
  Update name of object
335
-
336
- :param type: dialog type
337
- :param id: dialog object id
338
- :param name: new name
339
351
  """
340
- # ctx
352
+ # unchanged content...
341
353
  if type == 'ctx':
342
354
  self.window.controller.ctx.update_name(id, name)
343
355
  elif type == 'ctx.group':
344
356
  self.window.controller.ctx.update_group_name(id, name, True)
345
-
346
- # tab
347
357
  elif type == 'tab':
348
358
  self.window.controller.ui.tabs.update_name(id, name, True)
349
-
350
- # attachments and files
351
359
  elif type == 'attachment':
352
360
  self.window.controller.attachment.update_name(id, name)
353
361
  elif type == 'attachment_uploaded':
354
362
  self.window.controller.assistant.files.update_name(id, name)
355
363
  elif type == 'output_file':
356
364
  self.window.controller.files.update_name(id, name)
357
-
358
- # notepad
359
365
  elif type == 'notepad':
360
366
  self.window.controller.notepad.update_name(id, name, True)
361
-
362
- # plugin presets
363
367
  elif type == 'plugin.preset':
364
368
  self.window.controller.plugins.presets.update_name(id, name)
365
-
366
- # custom prompt templates rename
367
369
  elif type == 'prompt.custom.rename':
368
370
  self.window.controller.presets.rename_prompt(id, name, True)
369
-
370
- # custom prompt templates new
371
371
  elif type == 'prompt.custom.new':
372
372
  self.window.controller.presets.save_prompt(name, True)
373
-
374
- # tool: agent builder - create new agent
375
373
  elif type == 'agent.builder.agent':
376
374
  self.window.tools.get("agent_builder").rename_agent(id, name)
377
375
 
378
- def accept_create(
379
- self,
380
- type: str,
381
- id: any,
382
- name: str
383
- ):
376
+ def accept_create(self, type: str, id: any, name: str):
384
377
  """
385
378
  Create new object
386
-
387
- :param type: dialog type
388
- :param id: dialog object id
389
- :param name: name
390
379
  """
391
- # filesystem
380
+ # unchanged content...
392
381
  if type == 'mkdir':
393
382
  self.window.controller.files.make_dir(id, name)
394
383
  if type == 'touch':
395
384
  self.window.controller.files.touch_file(id, name, True)
396
385
  elif type == 'duplicate':
397
386
  self.window.controller.files.duplicate_local(id, name, True)
398
-
399
- # plugin presets
400
387
  elif type == 'plugin.preset':
401
388
  self.window.controller.plugins.presets.create(id, name)
402
-
403
- # ctx groups
404
389
  elif type == 'ctx.group':
405
390
  self.window.controller.ctx.create_group(name, id)
406
-
407
- # tool: agent builder - create new agent
408
391
  elif type == 'agent.builder.agent':
409
- self.window.tools.get("agent_builder").add_agent(name)
392
+ self.window.tools.get("agent_builder").add_agent(name)
393
+ elif type == 'remote_store.google.new':
394
+ self.window.controller.remote_store.google.new(name, True)
410
395
 
411
- def accept_url(
412
- self,
413
- type: str,
414
- id: any,
415
- url: str
416
- ):
396
+ def accept_url(self, type: str, id: any, url: str):
417
397
  """
418
398
  Update URL provided
419
-
420
- :param type: dialog type
421
- :param id: dialog object id
422
- :param url: URL
423
399
  """
424
- # add attachment
425
400
  if type == 'attachment':
426
401
  self.window.controller.attachment.add_url(url)
427
402
 
428
403
  def dismiss_rename(self):
429
- """Dismiss rename dialog"""
430
404
  self.window.ui.dialog['rename'].close()
431
405
 
432
406
  def dismiss_create(self):
433
- """Dismiss create dialog"""
434
407
  self.window.ui.dialog['create'].close()
435
408
 
436
409
  def dismiss_url(self):
437
- """Dismiss url dialog"""
438
- self.window.ui.dialog['url'].close()
410
+ self.window.ui.dialog['url'].close()
@@ -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.09.17 05:00:00 #
9
+ # Updated Date: 2026.01.02 20:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Dict
@@ -164,12 +164,12 @@ class Mapping:
164
164
  nodes['assistant.tool.function.label'] = 'assistant.functions.label'
165
165
 
166
166
  # assistants: vector store
167
- nodes['assistant.store.btn.new'] = 'dialog.assistant.store.btn.new'
168
- nodes['assistant.store.btn.save'] = 'dialog.assistant.store.btn.save'
169
- nodes['assistant.store.btn.upload.files'] = 'dialog.assistant.store.btn.upload.files'
170
- nodes['assistant.store.btn.upload.dir'] = 'dialog.assistant.store.btn.upload.dir'
171
- nodes['assistant.store.btn.close'] = 'dialog.assistant.store.btn.close'
172
- nodes['assistant.store.hide_thread'] = 'assistant.store.hide_threads'
167
+ nodes['remote_store.openai.btn.new'] = 'dialog.remote_store.btn.new'
168
+ nodes['remote_store.openai.btn.save'] = 'dialog.remote_store.btn.save'
169
+ nodes['remote_store.openai.btn.upload.files'] = 'dialog.remote_store.btn.upload.files'
170
+ nodes['remote_store.openai.btn.upload.dir'] = 'dialog.remote_store.btn.upload.dir'
171
+ nodes['remote_store.openai.btn.close'] = 'dialog.remote_store.btn.close'
172
+ nodes['remote_store.openai.hide_thread'] = 'remote_store.openai.hide_threads'
173
173
 
174
174
  # vision
175
175
  nodes['inline.vision'] = 'inline.vision'
@@ -402,7 +402,7 @@ class Mapping:
402
402
  dialog_title['config.editor'] = 'dialog.editor.title'
403
403
  dialog_title['config.settings'] = 'dialog.settings'
404
404
  dialog_title['editor.assistants'] = 'dialog.assistant'
405
- dialog_title['assistant.store'] = 'dialog.assistant.store'
405
+ dialog_title['remote_store.openai'] = 'dialog.remote_store.openai'
406
406
  dialog_title['editor.preset.presets'] = 'dialog.preset'
407
407
  dialog_title['image'] = 'dialog.image.title'
408
408
  dialog_title['interpreter'] = 'dialog.interpreter.title'
@@ -424,7 +424,7 @@ class Mapping:
424
424
  tooltips['icon.audio.output'] = 'icon.audio.output'
425
425
  tooltips['icon.audio.input'] = 'icon.audio.input'
426
426
  tooltips['icon.remote_tool.web'] = 'icon.remote_tool.web'
427
- tooltips['assistant.store.btn.refresh_status'] = 'dialog.assistant.store.btn.refresh_status'
427
+ tooltips['remote_store.openai.btn.refresh_status'] = 'dialog.remote_store.btn.refresh_status'
428
428
  tooltips['agent.llama.loop.score'] = 'toolbox.agent.llama.loop.score.tooltip'
429
429
 
430
430
  menu_tooltips = {}
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.12.14 08:00:00 #
9
+ # Updated Date: 2026.01.02 02:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import datetime
@@ -133,6 +133,55 @@ class Capture:
133
133
  print("Screenshot capture exception", e)
134
134
  self.window.core.debug.log(e)
135
135
 
136
+ def screenshot_playwright(
137
+ self,
138
+ page,
139
+ silent: bool = False
140
+ ) -> Optional[Union[str, bool]]:
141
+ """
142
+ Make screenshot and append to attachments
143
+
144
+ :param page : Playwright page
145
+ :param silent: Silent mode
146
+ :return: Path to screenshot or False if failed
147
+ """
148
+ if not silent:
149
+ # switch to vision mode if needed
150
+ self.window.controller.chat.vision.switch_to_vision()
151
+
152
+ # clear attachments before capture if needed
153
+ if self.window.controller.attachment.is_capture_clear():
154
+ self.window.controller.attachment.clear(True, auto=True)
155
+
156
+ try:
157
+ # prepare filename
158
+ now = datetime.datetime.now()
159
+ dt = now.strftime("%Y-%m-%d_%H-%M-%S")
160
+ name = 'cap-' + dt
161
+ path = os.path.join(self.window.controller.painter.common.get_capture_dir(), name + '.png')
162
+
163
+ # capture screenshot from page
164
+ if page:
165
+ page.screenshot(path=path, full_page=False)
166
+ else:
167
+ return False
168
+
169
+ self.attach(name, path, 'screenshot', silent=silent)
170
+
171
+ if not silent:
172
+ self.window.controller.painter.open(path)
173
+ # show last capture time in status
174
+ dt_info = now.strftime("%Y-%m-%d %H:%M:%S")
175
+ event = KernelEvent(KernelEvent.STATUS, {
176
+ 'status': trans("painter.capture.manual.captured.success") + ' ' + dt_info,
177
+ })
178
+ self.window.dispatch(event)
179
+ return path
180
+
181
+ except Exception as e:
182
+ print("Screenshot capture exception", e)
183
+ self.window.core.debug.log(e)
184
+
136
185
  def use(self):
137
186
  """Use current image"""
138
187
  # switch to vision mode if needed
@@ -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.12.27 21:00:00 #
9
+ # Updated Date: 2026.01.02 20:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import re
@@ -628,6 +628,7 @@ class Presets:
628
628
  mode = w.core.config.get('mode')
629
629
  if mode == MODE_ASSISTANT:
630
630
  w.core.assistants.load()
631
+ w.core.remote_store.openai.load_all()
631
632
 
632
633
  def _nearest_id_after_delete(self, mode: str, idx: Optional[int], deleting_id: Optional[str]) -> Optional[str]:
633
634
  """
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ================================================== #
4
+ # This file is a part of PYGPT package #
5
+ # Website: https://pygpt.net #
6
+ # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
+ # MIT License #
8
+ # Created By : Marcin Szczygliński #
9
+ # Updated Date: 2026.01.02 20:00:00 #
10
+ # ================================================== #
11
+
12
+ from .remote_store import *
@@ -6,7 +6,7 @@
6
6
  # GitHub: https://github.com/szczyglis-dev/py-gpt #
7
7
  # MIT License #
8
8
  # Created By : Marcin Szczygliński #
9
- # Updated Date: 2024.12.14 22:00:00 #
9
+ # Updated Date: 2026.01.02 20:00:00 #
10
10
  # ================================================== #
11
11
 
12
- from .provider import *
12
+ from .store import *