pygpt-net 2.7.3__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 (157) hide show
  1. pygpt_net/CHANGELOG.txt +15 -0
  2. pygpt_net/__init__.py +3 -3
  3. pygpt_net/app.py +382 -350
  4. pygpt_net/app_core.py +4 -2
  5. pygpt_net/controller/__init__.py +5 -1
  6. pygpt_net/controller/assistant/assistant.py +1 -4
  7. pygpt_net/controller/assistant/batch.py +5 -504
  8. pygpt_net/controller/assistant/editor.py +5 -5
  9. pygpt_net/controller/assistant/files.py +16 -16
  10. pygpt_net/controller/chat/attachment.py +5 -1
  11. pygpt_net/controller/chat/handler/google_stream.py +307 -1
  12. pygpt_net/controller/chat/handler/worker.py +8 -1
  13. pygpt_net/controller/chat/image.py +15 -3
  14. pygpt_net/controller/dialogs/confirm.py +73 -101
  15. pygpt_net/controller/files/files.py +3 -1
  16. pygpt_net/controller/lang/mapping.py +9 -9
  17. pygpt_net/controller/layout/layout.py +2 -2
  18. pygpt_net/controller/painter/capture.py +50 -1
  19. pygpt_net/controller/presets/presets.py +2 -1
  20. pygpt_net/controller/remote_store/__init__.py +12 -0
  21. pygpt_net/{provider/core/assistant_file/db_sqlite → controller/remote_store/google}/__init__.py +2 -2
  22. pygpt_net/controller/remote_store/google/batch.py +402 -0
  23. pygpt_net/controller/remote_store/google/store.py +615 -0
  24. pygpt_net/controller/remote_store/openai/__init__.py +12 -0
  25. pygpt_net/controller/remote_store/openai/batch.py +524 -0
  26. pygpt_net/controller/{assistant → remote_store/openai}/store.py +63 -60
  27. pygpt_net/controller/remote_store/remote_store.py +35 -0
  28. pygpt_net/controller/theme/nodes.py +2 -1
  29. pygpt_net/controller/ui/mode.py +5 -1
  30. pygpt_net/controller/ui/ui.py +36 -2
  31. pygpt_net/core/assistants/assistants.py +3 -15
  32. pygpt_net/core/db/database.py +5 -3
  33. pygpt_net/core/filesystem/url.py +4 -1
  34. pygpt_net/core/locale/placeholder.py +35 -0
  35. pygpt_net/core/remote_store/__init__.py +12 -0
  36. pygpt_net/core/remote_store/google/__init__.py +11 -0
  37. pygpt_net/core/remote_store/google/files.py +224 -0
  38. pygpt_net/core/remote_store/google/store.py +248 -0
  39. pygpt_net/core/remote_store/openai/__init__.py +11 -0
  40. pygpt_net/core/{assistants → remote_store/openai}/files.py +26 -19
  41. pygpt_net/core/{assistants → remote_store/openai}/store.py +32 -15
  42. pygpt_net/core/remote_store/remote_store.py +24 -0
  43. pygpt_net/core/render/web/helpers.py +5 -0
  44. pygpt_net/data/config/config.json +8 -5
  45. pygpt_net/data/config/models.json +77 -3
  46. pygpt_net/data/config/settings.json +45 -14
  47. pygpt_net/data/css/web-blocks.css +3 -0
  48. pygpt_net/data/css/web-chatgpt.css +3 -0
  49. pygpt_net/data/locale/locale.de.ini +43 -41
  50. pygpt_net/data/locale/locale.en.ini +56 -44
  51. pygpt_net/data/locale/locale.es.ini +43 -41
  52. pygpt_net/data/locale/locale.fr.ini +43 -41
  53. pygpt_net/data/locale/locale.it.ini +43 -41
  54. pygpt_net/data/locale/locale.pl.ini +43 -41
  55. pygpt_net/data/locale/locale.uk.ini +43 -41
  56. pygpt_net/data/locale/locale.zh.ini +43 -41
  57. pygpt_net/data/locale/plugin.cmd_history.de.ini +1 -1
  58. pygpt_net/data/locale/plugin.cmd_history.en.ini +1 -1
  59. pygpt_net/data/locale/plugin.cmd_history.es.ini +1 -1
  60. pygpt_net/data/locale/plugin.cmd_history.fr.ini +1 -1
  61. pygpt_net/data/locale/plugin.cmd_history.it.ini +1 -1
  62. pygpt_net/data/locale/plugin.cmd_history.pl.ini +1 -1
  63. pygpt_net/data/locale/plugin.cmd_history.uk.ini +1 -1
  64. pygpt_net/data/locale/plugin.cmd_history.zh.ini +1 -1
  65. pygpt_net/data/locale/plugin.cmd_mouse_control.en.ini +14 -0
  66. pygpt_net/data/locale/plugin.cmd_web.de.ini +1 -1
  67. pygpt_net/data/locale/plugin.cmd_web.en.ini +1 -1
  68. pygpt_net/data/locale/plugin.cmd_web.es.ini +1 -1
  69. pygpt_net/data/locale/plugin.cmd_web.fr.ini +1 -1
  70. pygpt_net/data/locale/plugin.cmd_web.it.ini +1 -1
  71. pygpt_net/data/locale/plugin.cmd_web.pl.ini +1 -1
  72. pygpt_net/data/locale/plugin.cmd_web.uk.ini +1 -1
  73. pygpt_net/data/locale/plugin.cmd_web.zh.ini +1 -1
  74. pygpt_net/data/locale/plugin.idx_llama_index.de.ini +2 -2
  75. pygpt_net/data/locale/plugin.idx_llama_index.en.ini +2 -2
  76. pygpt_net/data/locale/plugin.idx_llama_index.es.ini +2 -2
  77. pygpt_net/data/locale/plugin.idx_llama_index.fr.ini +2 -2
  78. pygpt_net/data/locale/plugin.idx_llama_index.it.ini +2 -2
  79. pygpt_net/data/locale/plugin.idx_llama_index.pl.ini +2 -2
  80. pygpt_net/data/locale/plugin.idx_llama_index.uk.ini +2 -2
  81. pygpt_net/data/locale/plugin.idx_llama_index.zh.ini +2 -2
  82. pygpt_net/item/assistant.py +1 -211
  83. pygpt_net/item/ctx.py +3 -1
  84. pygpt_net/item/store.py +238 -0
  85. pygpt_net/launcher.py +115 -55
  86. pygpt_net/migrations/Version20260102190000.py +35 -0
  87. pygpt_net/migrations/__init__.py +3 -1
  88. pygpt_net/plugin/cmd_mouse_control/config.py +470 -1
  89. pygpt_net/plugin/cmd_mouse_control/plugin.py +488 -22
  90. pygpt_net/plugin/cmd_mouse_control/worker.py +464 -87
  91. pygpt_net/plugin/cmd_mouse_control/worker_sandbox.py +729 -0
  92. pygpt_net/plugin/idx_llama_index/config.py +2 -2
  93. pygpt_net/preload.py +243 -0
  94. pygpt_net/provider/api/google/__init__.py +16 -54
  95. pygpt_net/provider/api/google/chat.py +546 -129
  96. pygpt_net/provider/api/google/computer.py +190 -0
  97. pygpt_net/provider/api/google/image.py +74 -6
  98. pygpt_net/provider/api/google/realtime/realtime.py +2 -2
  99. pygpt_net/provider/api/google/remote_tools.py +93 -0
  100. pygpt_net/provider/api/google/store.py +546 -0
  101. pygpt_net/provider/api/google/video.py +9 -4
  102. pygpt_net/provider/api/google/worker/__init__.py +0 -0
  103. pygpt_net/provider/api/google/worker/importer.py +392 -0
  104. pygpt_net/provider/api/openai/computer.py +10 -1
  105. pygpt_net/provider/api/openai/image.py +42 -19
  106. pygpt_net/provider/api/openai/store.py +6 -6
  107. pygpt_net/provider/api/openai/video.py +27 -2
  108. pygpt_net/provider/api/openai/worker/importer.py +24 -24
  109. pygpt_net/provider/api/x_ai/image.py +25 -2
  110. pygpt_net/provider/core/config/patch.py +23 -1
  111. pygpt_net/provider/core/config/patches/patch_before_2_6_42.py +3 -3
  112. pygpt_net/provider/core/model/patch.py +17 -3
  113. pygpt_net/provider/core/preset/json_file.py +13 -7
  114. pygpt_net/provider/core/{assistant_file → remote_file}/__init__.py +1 -1
  115. pygpt_net/provider/core/{assistant_file → remote_file}/base.py +9 -9
  116. pygpt_net/provider/core/remote_file/db_sqlite/__init__.py +12 -0
  117. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/patch.py +1 -1
  118. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/provider.py +23 -20
  119. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/storage.py +35 -27
  120. pygpt_net/provider/core/{assistant_file → remote_file}/db_sqlite/utils.py +5 -4
  121. pygpt_net/provider/core/{assistant_store → remote_store}/__init__.py +1 -1
  122. pygpt_net/provider/core/{assistant_store → remote_store}/base.py +10 -10
  123. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/__init__.py +1 -1
  124. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/patch.py +1 -1
  125. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/provider.py +16 -15
  126. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/storage.py +30 -23
  127. pygpt_net/provider/core/{assistant_store → remote_store}/db_sqlite/utils.py +5 -4
  128. pygpt_net/provider/core/{assistant_store → remote_store}/json_file.py +9 -9
  129. pygpt_net/provider/llms/google.py +2 -2
  130. pygpt_net/ui/base/config_dialog.py +3 -2
  131. pygpt_net/ui/dialog/assistant.py +3 -3
  132. pygpt_net/ui/dialog/plugins.py +3 -1
  133. pygpt_net/ui/dialog/remote_store_google.py +539 -0
  134. pygpt_net/ui/dialog/{assistant_store.py → remote_store_openai.py} +95 -95
  135. pygpt_net/ui/dialogs.py +5 -3
  136. pygpt_net/ui/layout/chat/attachments_uploaded.py +3 -3
  137. pygpt_net/ui/layout/chat/input.py +20 -2
  138. pygpt_net/ui/layout/chat/painter.py +6 -4
  139. pygpt_net/ui/layout/toolbox/computer_env.py +26 -8
  140. pygpt_net/ui/layout/toolbox/image.py +5 -5
  141. pygpt_net/ui/layout/toolbox/video.py +5 -4
  142. pygpt_net/ui/main.py +84 -3
  143. pygpt_net/ui/menu/tools.py +13 -5
  144. pygpt_net/ui/widget/dialog/base.py +3 -10
  145. pygpt_net/ui/widget/dialog/remote_store_google.py +56 -0
  146. pygpt_net/ui/widget/dialog/{assistant_store.py → remote_store_openai.py} +9 -9
  147. pygpt_net/ui/widget/element/button.py +4 -4
  148. pygpt_net/ui/widget/lists/remote_store_google.py +248 -0
  149. pygpt_net/ui/widget/lists/{assistant_store.py → remote_store_openai.py} +21 -21
  150. pygpt_net/ui/widget/option/checkbox_list.py +47 -9
  151. pygpt_net/ui/widget/option/combo.py +158 -4
  152. pygpt_net/ui/widget/textarea/input_extra.py +664 -0
  153. {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.dist-info}/METADATA +48 -9
  154. {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.dist-info}/RECORD +157 -130
  155. {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.dist-info}/LICENSE +0 -0
  156. {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.dist-info}/WHEEL +0 -0
  157. {pygpt_net-2.7.3.dist-info → pygpt_net-2.7.5.dist-info}/entry_points.txt +0 -0
@@ -6,21 +6,25 @@
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 00:00:00 #
9
+ # Updated Date: 2026.01.02 19:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  from typing import Optional, List, Dict, Union
13
13
 
14
14
  from packaging.version import Version
15
15
 
16
- from pygpt_net.item.assistant import AssistantFileItem, AssistantItem
17
- from pygpt_net.provider.core.assistant_file.db_sqlite import DbSqliteProvider
16
+ from pygpt_net.item.assistant import AssistantItem
17
+ from pygpt_net.item.store import RemoteFileItem
18
+ from pygpt_net.provider.core.remote_file.db_sqlite import DbSqliteProvider
18
19
 
19
20
 
20
21
  class Files:
22
+
23
+ PROVIDER_NAME = "openai"
24
+
21
25
  def __init__(self, window=None):
22
26
  """
23
- Assistant files core
27
+ OpenAI remote files core
24
28
 
25
29
  :param window: Window instance
26
30
  """
@@ -41,7 +45,7 @@ class Files:
41
45
  """
42
46
  return self.provider.patch(app_version)
43
47
 
44
- def get(self, id: str) -> AssistantFileItem:
48
+ def get(self, id: str) -> Optional[RemoteFileItem]:
45
49
  """
46
50
  Get file item by file_id
47
51
 
@@ -50,6 +54,7 @@ class Files:
50
54
  """
51
55
  if id in self.items:
52
56
  return self.items[id]
57
+ return None
53
58
 
54
59
  def get_ids(self) -> List[str]:
55
60
  """
@@ -60,7 +65,7 @@ class Files:
60
65
  return list(self.items.keys())
61
66
 
62
67
 
63
- def get_all(self) -> Dict[str, AssistantFileItem]:
68
+ def get_all(self) -> Dict[str, RemoteFileItem]:
64
69
  """
65
70
  Return all files
66
71
 
@@ -105,7 +110,7 @@ class Files:
105
110
  file_id: str,
106
111
  name: str,
107
112
  path: str,
108
- size: int) -> Optional[AssistantFileItem]:
113
+ size: int) -> Optional[RemoteFileItem]:
109
114
  """
110
115
  Create new file
111
116
 
@@ -117,10 +122,11 @@ class Files:
117
122
  :param size: file size
118
123
  :return: file item
119
124
  """
120
- file = AssistantFileItem()
125
+ file = RemoteFileItem()
121
126
  file.id = file_id
122
127
  file.file_id = file_id
123
128
  file.thread_id = thread_id
129
+ file.provider = self.PROVIDER_NAME
124
130
  file.name = name
125
131
  file.path = path
126
132
  file.size = size
@@ -132,8 +138,8 @@ class Files:
132
138
 
133
139
  def update(
134
140
  self,
135
- file: AssistantFileItem
136
- ) -> Optional[AssistantFileItem]:
141
+ file: RemoteFileItem
142
+ ) -> Optional[RemoteFileItem]:
137
143
  """
138
144
  Update file
139
145
 
@@ -160,7 +166,7 @@ class Files:
160
166
  self,
161
167
  store_id: str,
162
168
  thread_id: str
163
- ) -> Dict[str, AssistantFileItem]:
169
+ ) -> Dict[str, RemoteFileItem]:
164
170
  """
165
171
  Get files by store or thread
166
172
 
@@ -189,7 +195,7 @@ class Files:
189
195
  idx: int,
190
196
  store_id: str,
191
197
  thread_id: str
192
- ) -> Optional[AssistantFileItem]:
198
+ ) -> Optional[RemoteFileItem]:
193
199
  """
194
200
  Get file by list index
195
201
 
@@ -231,7 +237,7 @@ class Files:
231
237
  """
232
238
  return self.provider.get_all_by_file_id(file_id)
233
239
 
234
- def delete(self, file: Union[AssistantFileItem, list]) -> bool:
240
+ def delete(self, file: Union[RemoteFileItem, list]) -> bool:
235
241
  """
236
242
  Delete file and remove from vector stores if exists
237
243
 
@@ -287,7 +293,7 @@ class Files:
287
293
 
288
294
  def on_all_stores_deleted(self):
289
295
  """Clear all deleted stores from files"""
290
- self.provider.clear_all_stores_from_files()
296
+ self.provider.clear_all_stores_from_files(self.PROVIDER_NAME)
291
297
 
292
298
  def rename(self, record_id: int, name: str) -> bool:
293
299
  """
@@ -325,7 +331,7 @@ class Files:
325
331
  if store_id is not None:
326
332
  self.provider.truncate_by_store(store_id) # truncate files in DB (by store_id)
327
333
  else:
328
- self.provider.truncate_all() # truncate all files in DB
334
+ self.provider.truncate_all(self.PROVIDER_NAME) # truncate all files in DB
329
335
  self.items = {} # clear items
330
336
  return True
331
337
 
@@ -341,18 +347,19 @@ class Files:
341
347
  self.create(file.assistant, file.thread_id, file.file_id, file.name, file.path, file.size)
342
348
  return True
343
349
 
344
- def insert(self, store_id: str, data) -> AssistantFileItem:
350
+ def insert(self, store_id: str, data) -> RemoteFileItem:
345
351
  """
346
352
  Insert file object
347
353
 
348
354
  :param store_id: store ID
349
355
  :param data: file data from API
350
356
  """
351
- file = AssistantFileItem()
357
+ file = RemoteFileItem()
352
358
  file.id = data.id
353
359
  file.file_id = data.id
354
360
  file.thread_id = ""
355
361
  file.name = data.filename
362
+ file.provider = self.PROVIDER_NAME
356
363
  file.path = data.filename
357
364
  file.size = data.bytes
358
365
  file.store_id = store_id
@@ -361,8 +368,8 @@ class Files:
361
368
  return file
362
369
 
363
370
  def load(self):
364
- """Load file"""
365
- self.items = self.provider.load_all()
371
+ """Load files"""
372
+ self.items = self.provider.load_all(self.PROVIDER_NAME)
366
373
  self.sort_items()
367
374
 
368
375
  def sort_items(self):
@@ -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 20:00:00 #
10
10
  # ================================================== #
11
11
 
12
12
  import datetime
@@ -14,24 +14,31 @@ from typing import Optional, List, Dict, Any
14
14
 
15
15
  from packaging.version import Version
16
16
 
17
- from pygpt_net.item.assistant import AssistantStoreItem, AssistantItem
18
- from pygpt_net.provider.core.assistant_store.db_sqlite import DbSqliteProvider
17
+ from pygpt_net.item.store import RemoteStoreItem
18
+ from pygpt_net.provider.core.remote_store.db_sqlite import DbSqliteProvider
19
+
20
+ from .files import Files
19
21
 
20
22
 
21
23
  class Store:
24
+
25
+ PROVIDER_NAME = "openai"
26
+
22
27
  def __init__(self, window=None):
23
28
  """
24
- Assistant vector store core
29
+ OpenAI vector store core
25
30
 
26
31
  :param window: Window instance
27
32
  """
28
33
  self.window = window
29
34
  self.provider = DbSqliteProvider(window)
35
+ self.files = Files(window)
30
36
  self.items = {}
31
37
 
32
38
  def install(self):
33
39
  """Install provider data"""
34
40
  self.provider.install()
41
+ self.files.install()
35
42
 
36
43
  def patch(self, app_version: Version) -> bool:
37
44
  """
@@ -40,9 +47,11 @@ class Store:
40
47
  :param app_version: app version
41
48
  :return: True if data was patched
42
49
  """
43
- return self.provider.patch(app_version)
50
+ res1 = self.files.patch(app_version)
51
+ res2 = self.provider.patch(app_version)
52
+ return res1 or res2
44
53
 
45
- def get(self, id: str) -> AssistantStoreItem:
54
+ def get(self, id: str) -> RemoteStoreItem:
46
55
  """
47
56
  Get store item by store_id
48
57
 
@@ -61,7 +70,7 @@ class Store:
61
70
  return list(self.items.keys())
62
71
 
63
72
 
64
- def get_all(self) -> Dict[str, AssistantStoreItem]:
73
+ def get_all(self) -> Dict[str, RemoteStoreItem]:
65
74
  """
66
75
  Return all stores
67
76
 
@@ -99,7 +108,7 @@ class Store:
99
108
  """
100
109
  return id in self.items
101
110
 
102
- def create(self) -> Optional[AssistantStoreItem]:
111
+ def create(self) -> Optional[RemoteStoreItem]:
103
112
  """
104
113
  Create new store
105
114
 
@@ -109,15 +118,16 @@ class Store:
109
118
  vector_store = self.window.core.api.openai.store.create_store(name, 0)
110
119
  if vector_store is None:
111
120
  return None
112
- store = AssistantStoreItem()
121
+ store = RemoteStoreItem()
113
122
  store.id = vector_store.id
114
123
  store.name = name
124
+ store.provider = self.PROVIDER_NAME
115
125
  store.is_thread = False
116
126
  store.record_id = self.provider.create(store)
117
127
  self.items[store.id] = store
118
128
  return store
119
129
 
120
- def update(self, store: AssistantStoreItem) -> Optional[AssistantStoreItem]:
130
+ def update(self, store: RemoteStoreItem) -> Optional[RemoteStoreItem]:
121
131
  """
122
132
  Update store
123
133
 
@@ -184,12 +194,13 @@ class Store:
184
194
  if tmp_name is None:
185
195
  tmp_name = ""
186
196
  store.name = tmp_name
197
+ store.provider = self.PROVIDER_NAME
187
198
  self.append_status(store, status) # append to store
188
199
  self.update(store) # save to db
189
200
 
190
201
  def append_status(
191
202
  self,
192
- store: AssistantStoreItem,
203
+ store: RemoteStoreItem,
193
204
  status: Dict[str, Any]
194
205
  ):
195
206
  """
@@ -241,7 +252,7 @@ class Store:
241
252
  return True
242
253
  return False
243
254
 
244
- def import_items(self, items: Dict[str, AssistantStoreItem]):
255
+ def import_items(self, items: Dict[str, RemoteStoreItem]):
245
256
  """
246
257
  Insert items
247
258
 
@@ -249,6 +260,7 @@ class Store:
249
260
  """
250
261
  self.items = items
251
262
  for item in items.values():
263
+ item.provider = self.PROVIDER_NAME
252
264
  item.record_id = self.provider.create(item)
253
265
 
254
266
  def clear(self):
@@ -263,7 +275,7 @@ class Store:
263
275
  :return: True if store is hidden
264
276
  """
265
277
  if id in self.items:
266
- if (self.window.core.config.get("assistant.store.hide_threads")
278
+ if (self.window.core.config.get("remote_store.openai.hide_threads")
267
279
  and (self.items[id].name is None or self.items[id].name == "")):
268
280
  return True
269
281
  return False
@@ -274,15 +286,20 @@ class Store:
274
286
 
275
287
  :return: True if truncated
276
288
  """
277
- self.provider.truncate()
289
+ self.provider.truncate(self.PROVIDER_NAME)
278
290
  self.items = {}
279
291
  return True
280
292
 
281
293
  def load(self):
282
294
  """Load store"""
283
- self.items = self.provider.load_all()
295
+ self.items = self.provider.load_all(self.PROVIDER_NAME)
284
296
  self.sort_items()
285
297
 
298
+ def load_all(self):
299
+ """Load store"""
300
+ self.load()
301
+ self.files.load()
302
+
286
303
  def sort_items(self):
287
304
  """Sort items"""
288
305
  pass
@@ -0,0 +1,24 @@
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 .openai import Store as OpenAIStore
13
+ from .google import Store as GoogleStore
14
+
15
+ class RemoteStore:
16
+ def __init__(self, window=None):
17
+ """
18
+ Remote vector stores core
19
+
20
+ :param window: Window instance
21
+ """
22
+ self.window = window
23
+ self.openai = OpenAIStore(self.window)
24
+ self.google = GoogleStore(self.window)
@@ -17,6 +17,7 @@ class Helpers:
17
17
 
18
18
  _RE_HTML_ANGLE_OR_MATH = re.compile(r'(\\\[.*?\\\])|(<)|(>)', flags=re.DOTALL)
19
19
  _RE_WORKDIR_TOKEN = re.compile(r'\(%workdir%([^)]+)\)')
20
+ _RE_APPDIR_TOKEN = re.compile(r'\(%appdir%([^)]+)\)')
20
21
 
21
22
  _PLACEHOLDER_THINK_OPEN = "{{{{think}}}}"
22
23
  _PLACEHOLDER_THINK_CLOSE = "{{{{/think}}}}"
@@ -183,6 +184,10 @@ class Helpers:
183
184
  prefix = self.window.core.filesystem.get_workdir_prefix()
184
185
  s = self._RE_WORKDIR_TOKEN.sub(lambda m, p=prefix: f'({p}{m.group(1)})', s)
185
186
 
187
+ if "%appdir%" in s:
188
+ prefix = self.window.core.config.get_app_path()
189
+ s = self._RE_APPDIR_TOKEN.sub(lambda m, p=prefix: f'({p}{m.group(1)})', s)
190
+
186
191
  return s
187
192
 
188
193
  def post_format_text(self, text: str) -> str:
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.7.3",
4
- "app.version": "2.7.3",
5
- "updated_at": "2025-12-30T00:00:00"
3
+ "version": "2.7.5",
4
+ "app.version": "2.7.5",
5
+ "updated_at": "2026-01-03T00:00:00"
6
6
  },
7
7
  "access.audio.event.speech": false,
8
8
  "access.audio.event.speech.disabled": [],
@@ -106,7 +106,7 @@
106
106
  }
107
107
  ],
108
108
  "assistant": "",
109
- "assistant.store.hide_threads": true,
109
+ "remote_store.openai.hide_threads": true,
110
110
  "assistant_thread": "",
111
111
  "attachments_auto_index": true,
112
112
  "attachments_capture_clear": true,
@@ -419,10 +419,14 @@
419
419
  "remote_tools.anthropic.web_search": true,
420
420
  "remote_tools.code_interpreter": false,
421
421
  "remote_tools.computer_use.env": "",
422
+ "remote_tools.computer_use.sandbox": false,
422
423
  "remote_tools.file_search": false,
423
424
  "remote_tools.file_search.args": "",
424
425
  "remote_tools.global.web_search": true,
425
426
  "remote_tools.google.code_interpreter": false,
427
+ "remote_tools.google.file_search": false,
428
+ "remote_tools.google.file_search.args": "",
429
+ "remote_tools.google.maps": false,
426
430
  "remote_tools.google.url_ctx": false,
427
431
  "remote_tools.google.web_search": true,
428
432
  "remote_tools.image": false,
@@ -538,7 +542,6 @@
538
542
  "video.duration": 8,
539
543
  "video.fps": 24,
540
544
  "video.generate_audio": false,
541
- "video.negative_prompt": "",
542
545
  "video.player.path": "",
543
546
  "video.player.volume": 100,
544
547
  "video.player.volume.mute": false,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "__meta__": {
3
- "version": "2.7.3",
4
- "app.version": "2.7.3",
5
- "updated_at": "2025-12-30T00:00:00"
3
+ "version": "2.7.5",
4
+ "app.version": "2.7.5",
5
+ "updated_at": "2026-01-03T00:00:00"
6
6
  },
7
7
  "items": {
8
8
  "SpeakLeash/bielik-11b-v2.3-instruct:Q4_K_M": {
@@ -570,6 +570,44 @@
570
570
  "provider": "openai",
571
571
  "tool_calls": false
572
572
  },
573
+ "deep-research-pro-preview-12-2025": {
574
+ "id": "deep-research-pro-preview-12-2025",
575
+ "name": "deep-research-pro-preview-12-2025",
576
+ "mode": [
577
+ "research"
578
+ ],
579
+ "llama_index": {
580
+ "args": [
581
+ {
582
+ "name": "model",
583
+ "value": "models/deep-research-pro-preview-12-2025",
584
+ "type": "str"
585
+ }
586
+ ],
587
+ "env": [
588
+ {
589
+ "name": "GOOGLE_API_KEY",
590
+ "value": "{api_key_google}",
591
+ "type": "str"
592
+ }
593
+ ]
594
+ },
595
+ "ctx": 1000000,
596
+ "tokens": 0,
597
+ "default": false,
598
+ "input": [
599
+ "text",
600
+ "image"
601
+ ],
602
+ "output": [
603
+ "text",
604
+ "image"
605
+ ],
606
+ "extra": {},
607
+ "imported": false,
608
+ "provider": "google",
609
+ "tool_calls": true
610
+ },
573
611
  "deepseek_api_reasoner": {
574
612
  "id": "deepseek-reasoner",
575
613
  "name": "DeepSeek API (R1, reasoner)",
@@ -912,6 +950,42 @@
912
950
  "provider": "google",
913
951
  "tool_calls": true
914
952
  },
953
+ "gemini-2.5-computer-use-preview-10-2025": {
954
+ "id": "gemini-2.5-computer-use-preview-10-2025",
955
+ "name": "gemini-2.5-computer-use-preview-10-2025",
956
+ "mode": [
957
+ "computer"
958
+ ],
959
+ "llama_index": {
960
+ "args": [
961
+ {
962
+ "name": "model",
963
+ "value": "models/gemini-2.5-computer-use-preview-10-2025",
964
+ "type": "str"
965
+ }
966
+ ],
967
+ "env": [
968
+ {
969
+ "name": "GOOGLE_API_KEY",
970
+ "value": "{api_key_google}",
971
+ "type": "str"
972
+ }
973
+ ]
974
+ },
975
+ "ctx": 128000,
976
+ "tokens": 0,
977
+ "default": false,
978
+ "input": [
979
+ "text"
980
+ ],
981
+ "output": [
982
+ "text"
983
+ ],
984
+ "extra": {},
985
+ "imported": false,
986
+ "provider": "google",
987
+ "tool_calls": true
988
+ },
915
989
  "gemini-2.5-flash": {
916
990
  "id": "gemini-2.5-flash",
917
991
  "name": "gemini-2.5-flash",
@@ -1608,20 +1608,6 @@
1608
1608
  "advanced": false,
1609
1609
  "tab": "video"
1610
1610
  },
1611
- "video.negative_prompt": {
1612
- "section": "images",
1613
- "type": "textarea",
1614
- "slider": false,
1615
- "label": "settings.video.negative_prompt",
1616
- "description": "settings.video.negative_prompt.desc",
1617
- "value": "",
1618
- "min": null,
1619
- "max": null,
1620
- "multiplier": null,
1621
- "step": null,
1622
- "advanced": false,
1623
- "tab": "video"
1624
- },
1625
1611
  "video.prompt_model": {
1626
1612
  "section": "images",
1627
1613
  "type": "combo",
@@ -1976,6 +1962,20 @@
1976
1962
  "advanced": false,
1977
1963
  "tab": "Google"
1978
1964
  },
1965
+ "remote_tools.google.maps": {
1966
+ "section": "remote_tools",
1967
+ "type": "bool",
1968
+ "slider": false,
1969
+ "label": "settings.remote_tools.google.maps",
1970
+ "description": "settings.remote_tools.google.maps.desc",
1971
+ "value": true,
1972
+ "min": null,
1973
+ "max": null,
1974
+ "multiplier": null,
1975
+ "step": null,
1976
+ "advanced": false,
1977
+ "tab": "Google"
1978
+ },
1979
1979
  "remote_tools.google.code_interpreter": {
1980
1980
  "section": "remote_tools",
1981
1981
  "type": "bool",
@@ -2004,6 +2004,37 @@
2004
2004
  "advanced": false,
2005
2005
  "tab": "Google"
2006
2006
  },
2007
+ "remote_tools.google.file_search": {
2008
+ "section": "remote_tools",
2009
+ "type": "bool",
2010
+ "slider": false,
2011
+ "label": "settings.remote_tools.google.file_search",
2012
+ "description": "settings.remote_tools.google.file_search.desc",
2013
+ "value": true,
2014
+ "min": null,
2015
+ "max": null,
2016
+ "multiplier": null,
2017
+ "step": null,
2018
+ "advanced": false,
2019
+ "tab": "Google"
2020
+ },
2021
+ "remote_tools.google.file_search.args": {
2022
+ "section": "remote_tools",
2023
+ "type": "text",
2024
+ "slider": false,
2025
+ "label": "settings.remote_tools.google.file_search.args",
2026
+ "description": "settings.remote_tools.google.file_search.args.desc",
2027
+ "value": "",
2028
+ "min": null,
2029
+ "max": null,
2030
+ "multiplier": null,
2031
+ "step": null,
2032
+ "advanced": false,
2033
+ "tab": "Google",
2034
+ "urls": {
2035
+ "Google Docs": "https://ai.google.dev/gemini-api/docs/file-search?hl=pl#metadata"
2036
+ }
2037
+ },
2007
2038
  "remote_tools.anthropic.web_search": {
2008
2039
  "section": "remote_tools",
2009
2040
  "type": "bool",
@@ -17,6 +17,9 @@ body {{
17
17
  padding: 0;
18
18
  max-width: 100%;
19
19
  }}
20
+ img {{
21
+ vertical-align: middle;
22
+ }}
20
23
  ::-webkit-scrollbar {{
21
24
  height: 12px;
22
25
  width: 12px;
@@ -18,6 +18,9 @@ body {{
18
18
  max-width: 720px;
19
19
  border-radius: .25rem;
20
20
  }}
21
+ img {{
22
+ vertical-align: middle;
23
+ }}
21
24
  ::-webkit-scrollbar {{
22
25
  height: 12px;
23
26
  width: 12px;