pygpt-net 2.6.17.post1__py3-none-any.whl → 2.6.19__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.
- pygpt_net/CHANGELOG.txt +10 -0
- pygpt_net/__init__.py +3 -3
- pygpt_net/app.py +2 -0
- pygpt_net/controller/chat/output.py +2 -2
- pygpt_net/controller/chat/response.py +17 -28
- pygpt_net/core/agents/observer/evaluation.py +9 -9
- pygpt_net/core/agents/runner.py +53 -42
- pygpt_net/core/agents/tools.py +59 -40
- pygpt_net/core/experts/experts.py +32 -366
- pygpt_net/core/experts/worker.py +362 -0
- pygpt_net/core/idx/chat.py +49 -82
- pygpt_net/core/idx/context.py +10 -14
- pygpt_net/core/idx/idx.py +19 -8
- pygpt_net/core/idx/indexing.py +35 -38
- pygpt_net/core/idx/response.py +91 -2
- pygpt_net/core/idx/worker.py +3 -8
- pygpt_net/core/render/web/body.py +18 -1
- pygpt_net/core/render/web/renderer.py +28 -13
- pygpt_net/core/types/__init__.py +2 -1
- pygpt_net/core/types/tools.py +22 -0
- pygpt_net/data/config/config.json +4 -4
- pygpt_net/data/config/models.json +3 -3
- pygpt_net/data/config/presets/current.llama_index.json +1 -1
- pygpt_net/provider/agents/openai/evolve.py +1 -1
- pygpt_net/provider/gpt/summarizer.py +4 -0
- pygpt_net/ui/widget/filesystem/explorer.py +7 -9
- pygpt_net/utils.py +2 -0
- {pygpt_net-2.6.17.post1.dist-info → pygpt_net-2.6.19.dist-info}/METADATA +12 -2
- {pygpt_net-2.6.17.post1.dist-info → pygpt_net-2.6.19.dist-info}/RECORD +32 -30
- {pygpt_net-2.6.17.post1.dist-info → pygpt_net-2.6.19.dist-info}/LICENSE +0 -0
- {pygpt_net-2.6.17.post1.dist-info → pygpt_net-2.6.19.dist-info}/WHEEL +0 -0
- {pygpt_net-2.6.17.post1.dist-info → pygpt_net-2.6.19.dist-info}/entry_points.txt +0 -0
pygpt_net/core/idx/context.py
CHANGED
|
@@ -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.
|
|
9
|
+
# Updated Date: 2025.08.21 07:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import os
|
|
@@ -46,7 +46,7 @@ class Context:
|
|
|
46
46
|
prev_message = None,
|
|
47
47
|
allow_native_tool_calls: bool = False,
|
|
48
48
|
attachments: Dict[str, AttachmentItem] = None,
|
|
49
|
-
):
|
|
49
|
+
) -> List[ChatMessage]:
|
|
50
50
|
"""
|
|
51
51
|
Get messages from db
|
|
52
52
|
|
|
@@ -57,7 +57,7 @@ class Context:
|
|
|
57
57
|
:param prev_message: previous message
|
|
58
58
|
:param allow_native_tool_calls: allow native tool calls
|
|
59
59
|
:param attachments: attachments
|
|
60
|
-
:return:
|
|
60
|
+
:return: List of ChatMessage objects
|
|
61
61
|
"""
|
|
62
62
|
messages = []
|
|
63
63
|
|
|
@@ -155,17 +155,13 @@ class Context:
|
|
|
155
155
|
|
|
156
156
|
:param query: input query
|
|
157
157
|
:param attachments: attachments
|
|
158
|
+
:return: ChatMessage object
|
|
158
159
|
"""
|
|
159
|
-
blocks = []
|
|
160
|
-
blocks.append(
|
|
161
|
-
TextBlock(text=query)
|
|
162
|
-
)
|
|
160
|
+
blocks = [TextBlock(text=query)]
|
|
163
161
|
|
|
164
162
|
self.attachments = {} # reset attachments, only current prompt
|
|
165
163
|
self.urls = []
|
|
166
164
|
|
|
167
|
-
#https://pygpt.net/assets/img/img3.jpg?v=2024-11-28
|
|
168
|
-
|
|
169
165
|
# extract URLs from prompt
|
|
170
166
|
urls = self.extract_urls(query)
|
|
171
167
|
if len(urls) > 0:
|
|
@@ -186,14 +182,12 @@ class Context:
|
|
|
186
182
|
)
|
|
187
183
|
self.attachments[id] = attachment.path
|
|
188
184
|
|
|
189
|
-
|
|
185
|
+
return ChatMessage(
|
|
190
186
|
role=MessageRole.USER,
|
|
191
187
|
blocks=blocks,
|
|
192
188
|
)
|
|
193
|
-
return msg
|
|
194
|
-
|
|
195
|
-
|
|
196
189
|
|
|
190
|
+
"""
|
|
197
191
|
urls.append(attachment.path)
|
|
198
192
|
msg = ChatMessage(
|
|
199
193
|
role=MessageRole.USER,
|
|
@@ -208,12 +202,14 @@ class Context:
|
|
|
208
202
|
image_documents=image_documents,
|
|
209
203
|
)
|
|
210
204
|
return msg
|
|
205
|
+
"""
|
|
211
206
|
|
|
212
207
|
def add_system(self, prompt: str) -> ChatMessage:
|
|
213
208
|
"""
|
|
214
209
|
Add system message to db
|
|
215
210
|
|
|
216
211
|
:param prompt: system prompt
|
|
212
|
+
:return: ChatMessage object
|
|
217
213
|
"""
|
|
218
214
|
return ChatMessage(
|
|
219
215
|
role=MessageRole.SYSTEM,
|
|
@@ -224,7 +220,7 @@ class Context:
|
|
|
224
220
|
"""
|
|
225
221
|
Append images content to context item
|
|
226
222
|
|
|
227
|
-
:param ctx: context
|
|
223
|
+
:param ctx: context item
|
|
228
224
|
"""
|
|
229
225
|
images = self.get_attachments() # dict -> key: id, value: path
|
|
230
226
|
urls = self.get_urls() # list
|
pygpt_net/core/idx/idx.py
CHANGED
|
@@ -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.
|
|
9
|
+
# Updated Date: 2025.08.21 07:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import datetime
|
|
@@ -78,6 +78,17 @@ class Idx:
|
|
|
78
78
|
self.load()
|
|
79
79
|
self.initialized = True
|
|
80
80
|
|
|
81
|
+
def is_valid(self, idx: str = None) -> bool:
|
|
82
|
+
"""
|
|
83
|
+
Check if index is valid
|
|
84
|
+
|
|
85
|
+
:param idx: index name
|
|
86
|
+
:return: True if index is valid
|
|
87
|
+
"""
|
|
88
|
+
if idx and idx != "_":
|
|
89
|
+
return self.has(idx)
|
|
90
|
+
return False
|
|
91
|
+
|
|
81
92
|
def get_current_store(self) -> str:
|
|
82
93
|
"""
|
|
83
94
|
Get current vector store name/ID
|
|
@@ -166,7 +177,7 @@ class Idx:
|
|
|
166
177
|
) # store index
|
|
167
178
|
|
|
168
179
|
if errors:
|
|
169
|
-
self.log("Error: "
|
|
180
|
+
self.log(f"Error: {errors}")
|
|
170
181
|
return files, errors
|
|
171
182
|
|
|
172
183
|
def index_db_by_meta_id(
|
|
@@ -202,7 +213,7 @@ class Idx:
|
|
|
202
213
|
) # store index
|
|
203
214
|
|
|
204
215
|
if errors:
|
|
205
|
-
self.log("Error: "
|
|
216
|
+
self.log(f"Error: {errors}")
|
|
206
217
|
return num, errors
|
|
207
218
|
|
|
208
219
|
def index_db_from_updated_ts(
|
|
@@ -235,7 +246,7 @@ class Idx:
|
|
|
235
246
|
) # store index
|
|
236
247
|
|
|
237
248
|
if errors:
|
|
238
|
-
self.log("Error: "
|
|
249
|
+
self.log(f"Error: {errors}")
|
|
239
250
|
return num, errors
|
|
240
251
|
|
|
241
252
|
def index_urls(
|
|
@@ -274,7 +285,7 @@ class Idx:
|
|
|
274
285
|
) # store index
|
|
275
286
|
|
|
276
287
|
if errors:
|
|
277
|
-
self.log("Error: "
|
|
288
|
+
self.log(f"Error: {errors}")
|
|
278
289
|
return n, errors
|
|
279
290
|
|
|
280
291
|
def index_web(
|
|
@@ -320,7 +331,7 @@ class Idx:
|
|
|
320
331
|
) # store index
|
|
321
332
|
|
|
322
333
|
if errors:
|
|
323
|
-
self.log("Error: "
|
|
334
|
+
self.log(f"Error: {errors}")
|
|
324
335
|
return n, errors
|
|
325
336
|
|
|
326
337
|
def get_idx_data(
|
|
@@ -478,7 +489,7 @@ class Idx:
|
|
|
478
489
|
"""
|
|
479
490
|
self.llm.get_service_context(stream=False) # init environment only (ENV API keys, etc.)
|
|
480
491
|
if self.storage.remove_document(idx, doc_id):
|
|
481
|
-
self.log("Removed document from index:
|
|
492
|
+
self.log(f"Removed document from index: {idx} - {doc_id}")
|
|
482
493
|
|
|
483
494
|
def remove_file(
|
|
484
495
|
self,
|
|
@@ -592,5 +603,5 @@ class Idx:
|
|
|
592
603
|
is_log = True
|
|
593
604
|
self.window.core.debug.info(msg, not is_log)
|
|
594
605
|
if is_log:
|
|
595
|
-
print("[
|
|
606
|
+
print(f"[LlamaIndex] {msg}")
|
|
596
607
|
self.window.idx_logger_message.emit(msg)
|
pygpt_net/core/idx/indexing.py
CHANGED
|
@@ -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.
|
|
9
|
+
# Updated Date: 2025.08.21 07:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
import datetime
|
|
@@ -53,7 +53,7 @@ class Indexing:
|
|
|
53
53
|
# check if compiled version is allowed
|
|
54
54
|
is_compiled = self.window.core.config.is_compiled() or self.window.core.platforms.is_snap()
|
|
55
55
|
if not loader.allow_compiled and is_compiled:
|
|
56
|
-
self.window.core.idx.log("Loader not allowed in compiled version:
|
|
56
|
+
self.window.core.idx.log(f"Loader not allowed in compiled version: {loader.id}" )
|
|
57
57
|
return
|
|
58
58
|
|
|
59
59
|
loader.attach_window(self.window)
|
|
@@ -67,7 +67,7 @@ class Indexing:
|
|
|
67
67
|
for ext in extensions:
|
|
68
68
|
self.loaders["file"][ext] = loader # set reader instance, by file extension
|
|
69
69
|
except ImportError as e:
|
|
70
|
-
msg = "Error while registering data loader:
|
|
70
|
+
msg = f"Error while registering data loader: {loader.id} - {e}"
|
|
71
71
|
self.window.core.debug.log(msg)
|
|
72
72
|
self.window.core.debug.log(e)
|
|
73
73
|
|
|
@@ -101,7 +101,7 @@ class Indexing:
|
|
|
101
101
|
self.external_config[loader.id][key]["description"] = loader.init_args_desc[key]
|
|
102
102
|
|
|
103
103
|
except ImportError as e:
|
|
104
|
-
msg = "Error while registering data loader:
|
|
104
|
+
msg = f"Error while registering data loader: {loader.id} - {e}"
|
|
105
105
|
self.window.core.debug.log(msg)
|
|
106
106
|
self.window.core.debug.log(e)
|
|
107
107
|
|
|
@@ -305,7 +305,7 @@ class Indexing:
|
|
|
305
305
|
"""
|
|
306
306
|
# TODO: if .zip then unpack here, and return path to /tmp
|
|
307
307
|
if not silent:
|
|
308
|
-
self.window.core.idx.log("Reading documents from path: {}"
|
|
308
|
+
self.window.core.idx.log(f"Reading documents from path: {path}")
|
|
309
309
|
if os.path.isdir(path):
|
|
310
310
|
reader = SimpleDirectoryReader(
|
|
311
311
|
input_dir=path,
|
|
@@ -320,13 +320,13 @@ class Indexing:
|
|
|
320
320
|
# check if not excluded extension
|
|
321
321
|
if self.is_excluded(ext) and not force:
|
|
322
322
|
if not silent:
|
|
323
|
-
self.window.core.idx.log("Ignoring excluded extension: {}"
|
|
323
|
+
self.window.core.idx.log(f"Ignoring excluded extension: {ext}")
|
|
324
324
|
return []
|
|
325
325
|
|
|
326
326
|
# check if not excluded path
|
|
327
327
|
if self.is_excluded_path(path) and not force:
|
|
328
328
|
if not silent:
|
|
329
|
-
self.window.core.idx.log("Ignoring excluded path: {}"
|
|
329
|
+
self.window.core.idx.log(f"Ignoring excluded path: {path}")
|
|
330
330
|
return []
|
|
331
331
|
|
|
332
332
|
# check if archive (zip, tar)
|
|
@@ -337,7 +337,7 @@ class Indexing:
|
|
|
337
337
|
|
|
338
338
|
if ext in self.loaders["file"]:
|
|
339
339
|
if not silent:
|
|
340
|
-
self.window.core.idx.log("Using loader for: {}"
|
|
340
|
+
self.window.core.idx.log(f"Using loader for: {ext}")
|
|
341
341
|
reader = self.loaders["file"][ext].get() # get data reader instance
|
|
342
342
|
|
|
343
343
|
# use custom loader method if available
|
|
@@ -347,7 +347,7 @@ class Indexing:
|
|
|
347
347
|
documents = reader.load_data(file=Path(path))
|
|
348
348
|
else:
|
|
349
349
|
if not silent:
|
|
350
|
-
self.window.core.idx.log("Using default SimpleDirectoryReader for: {}"
|
|
350
|
+
self.window.core.idx.log(f"Using default SimpleDirectoryReader for: {ext}")
|
|
351
351
|
reader = SimpleDirectoryReader(input_files=[path])
|
|
352
352
|
documents = reader.load_data()
|
|
353
353
|
|
|
@@ -424,8 +424,8 @@ class Indexing:
|
|
|
424
424
|
|
|
425
425
|
# get unique external content identifier
|
|
426
426
|
unique_id = self.data_providers[type].get_external_id(extra_args)
|
|
427
|
-
self.window.core.idx.log("Loading web documents from: {}"
|
|
428
|
-
self.window.core.idx.log("Using web loader for type: {}"
|
|
427
|
+
self.window.core.idx.log(f"Loading web documents from: {unique_id}")
|
|
428
|
+
self.window.core.idx.log(f"Using web loader for type: {type}")
|
|
429
429
|
|
|
430
430
|
args = self.data_providers[type].prepare_args(**extra_args)
|
|
431
431
|
|
|
@@ -509,10 +509,10 @@ class Indexing:
|
|
|
509
509
|
self.prepare_document(d)
|
|
510
510
|
self.index_document(index, d)
|
|
511
511
|
indexed[file] = d.id_ # add to index
|
|
512
|
-
self.window.core.idx.log("Inserted document: {}, metadata: {
|
|
512
|
+
self.window.core.idx.log(f"Inserted document: {d.id_}, metadata: {d.metadata}")
|
|
513
513
|
except Exception as e:
|
|
514
514
|
errors.append(str(e))
|
|
515
|
-
print("Error while indexing file: "
|
|
515
|
+
print(f"Error while indexing file: {file}")
|
|
516
516
|
self.window.core.debug.log(e)
|
|
517
517
|
if self.stop_enabled():
|
|
518
518
|
break # break loop if error
|
|
@@ -571,10 +571,10 @@ class Indexing:
|
|
|
571
571
|
self.prepare_document(d)
|
|
572
572
|
self.index_document(index, d)
|
|
573
573
|
indexed[file_path] = d.id_ # add to index
|
|
574
|
-
self.window.core.idx.log("Inserted document: {}, metadata: {
|
|
574
|
+
self.window.core.idx.log(f"Inserted document: {d.id_}, metadata: {d.metadata}")
|
|
575
575
|
except Exception as e:
|
|
576
576
|
errors.append(str(e))
|
|
577
|
-
print("Error while indexing file: "
|
|
577
|
+
print(f"Error while indexing file: {file_path}")
|
|
578
578
|
self.window.core.debug.log(e)
|
|
579
579
|
if self.stop_enabled():
|
|
580
580
|
is_break = True
|
|
@@ -607,10 +607,10 @@ class Indexing:
|
|
|
607
607
|
self.prepare_document(d)
|
|
608
608
|
self.index_document(index, d)
|
|
609
609
|
indexed[path] = d.id_ # add to index
|
|
610
|
-
self.window.core.idx.log("Inserted document: {}, metadata: {
|
|
610
|
+
self.window.core.idx.log(f"Inserted document: {d.id_}, metadata: {d.metadata}")
|
|
611
611
|
except Exception as e:
|
|
612
612
|
errors.append(str(e))
|
|
613
|
-
print("Error while indexing file: "
|
|
613
|
+
print(f"Error while indexing file: {path}")
|
|
614
614
|
self.window.core.debug.log(e)
|
|
615
615
|
|
|
616
616
|
return indexed, errors
|
|
@@ -748,11 +748,10 @@ class Indexing:
|
|
|
748
748
|
try:
|
|
749
749
|
# remove old document from index if indexing by ID only and not from timestamp
|
|
750
750
|
if from_ts == 0:
|
|
751
|
-
self.window.core.idx.log("Indexing documents from database by meta id: {}"
|
|
751
|
+
self.window.core.idx.log(f"Indexing documents from database by meta id: {id}")
|
|
752
752
|
self.remove_old_meta_id(idx, id)
|
|
753
753
|
elif from_ts > 0:
|
|
754
|
-
self.window.core.idx.log("Indexing documents from database by meta id: {} from timestamp: {}"
|
|
755
|
-
format(id, from_ts))
|
|
754
|
+
self.window.core.idx.log(f"Indexing documents from database by meta id: {id} from timestamp: {from_ts}")
|
|
756
755
|
|
|
757
756
|
# get items from database
|
|
758
757
|
documents = self.get_db_data_by_id(id, from_ts)
|
|
@@ -762,8 +761,7 @@ class Indexing:
|
|
|
762
761
|
|
|
763
762
|
self.index_document(index, d)
|
|
764
763
|
doc_id = d.id_
|
|
765
|
-
self.window.core.idx.log("Inserted ctx DB document: {} / {}, id: {}, metadata: {}"
|
|
766
|
-
format(n+1, len(documents), d.id_, d.metadata))
|
|
764
|
+
self.window.core.idx.log(f"Inserted ctx DB document: {n+1} / {len(documents)}, id: {d.id_}, metadata: {d.metadata}")
|
|
767
765
|
self.window.core.ctx.idx.set_meta_as_indexed(id, idx, doc_id) # update ctx
|
|
768
766
|
n += 1
|
|
769
767
|
except Exception as e:
|
|
@@ -785,7 +783,7 @@ class Indexing:
|
|
|
785
783
|
:param from_ts: timestamp
|
|
786
784
|
:return: number of indexed documents, errors
|
|
787
785
|
"""
|
|
788
|
-
self.window.core.idx.log("Indexing documents from database from timestamp: {}"
|
|
786
|
+
self.window.core.idx.log(f"Indexing documents from database from timestamp: {from_ts}")
|
|
789
787
|
errors = []
|
|
790
788
|
n = 0
|
|
791
789
|
ids = self.get_db_meta_ids_from_ts(from_ts)
|
|
@@ -825,7 +823,7 @@ class Indexing:
|
|
|
825
823
|
|
|
826
824
|
# check if web loader for defined type exists
|
|
827
825
|
if type not in self.loaders["web"]:
|
|
828
|
-
raise ValueError("No web loader for type: {}"
|
|
826
|
+
raise ValueError(f"No web loader for type: {type}")
|
|
829
827
|
|
|
830
828
|
try:
|
|
831
829
|
# remove old content from index if already indexed
|
|
@@ -851,8 +849,8 @@ class Indexing:
|
|
|
851
849
|
if not is_tmp:
|
|
852
850
|
self.remove_old_external(idx, unique_id, type)
|
|
853
851
|
|
|
854
|
-
self.window.core.idx.log("Loading web documents from: {}"
|
|
855
|
-
self.window.core.idx.log("Using web loader for type: {}"
|
|
852
|
+
self.window.core.idx.log(f"Loading web documents from: {unique_id}")
|
|
853
|
+
self.window.core.idx.log(f"Using web loader for type: {type}")
|
|
856
854
|
|
|
857
855
|
args = self.data_providers[type].prepare_args(**extra_args)
|
|
858
856
|
|
|
@@ -877,8 +875,7 @@ class Indexing:
|
|
|
877
875
|
idx=idx,
|
|
878
876
|
doc_id=doc_id,
|
|
879
877
|
) # update external index
|
|
880
|
-
self.window.core.idx.log("Inserted web document: {} / {}, id: {}, metadata: {}"
|
|
881
|
-
format(n+1, len(documents), d.id_, d.metadata))
|
|
878
|
+
self.window.core.idx.log(f"Inserted web document: {n+1} / {len(documents)}, id: {d.id_}, metadata: {d.metadata}")
|
|
882
879
|
n += 1
|
|
883
880
|
except Exception as e:
|
|
884
881
|
errors.append(str(e))
|
|
@@ -910,7 +907,7 @@ class Indexing:
|
|
|
910
907
|
|
|
911
908
|
# check if web loader for defined type exists
|
|
912
909
|
if type not in self.loaders["web"]:
|
|
913
|
-
msg = "No web loader for type: {}"
|
|
910
|
+
msg = f"No web loader for type: {type}"
|
|
914
911
|
errors.append(msg)
|
|
915
912
|
self.window.core.debug.log(msg)
|
|
916
913
|
return n, errors
|
|
@@ -953,7 +950,7 @@ class Indexing:
|
|
|
953
950
|
if self.window.core.idx.ctx.exists(store, idx, id):
|
|
954
951
|
doc_id = self.window.core.idx.ctx.get_doc_id(store, idx, id)
|
|
955
952
|
if doc_id:
|
|
956
|
-
self.window.core.idx.log("Removing old document id: {}"
|
|
953
|
+
self.window.core.idx.log(f"Removing old document id: {doc_id}")
|
|
957
954
|
try:
|
|
958
955
|
self.window.core.idx.storage.remove_document(
|
|
959
956
|
id=idx,
|
|
@@ -986,7 +983,7 @@ class Indexing:
|
|
|
986
983
|
if self.window.core.idx.files.exists(store, idx, file_id):
|
|
987
984
|
doc_id = self.window.core.idx.files.get_doc_id(store, idx, file_id)
|
|
988
985
|
if doc_id:
|
|
989
|
-
self.window.core.idx.log("Removing old document id: {}"
|
|
986
|
+
self.window.core.idx.log(f"Removing old document id: {doc_id}")
|
|
990
987
|
try:
|
|
991
988
|
self.window.core.idx.storage.remove_document(
|
|
992
989
|
id=idx,
|
|
@@ -1021,7 +1018,7 @@ class Indexing:
|
|
|
1021
1018
|
if self.window.core.idx.external.exists(store, idx, content, type):
|
|
1022
1019
|
doc_id = self.window.core.idx.external.get_doc_id(store, idx, content, type)
|
|
1023
1020
|
if doc_id:
|
|
1024
|
-
self.window.core.idx.log("Removing old document id: {}"
|
|
1021
|
+
self.window.core.idx.log(f"Removing old document id: {doc_id}")
|
|
1025
1022
|
try:
|
|
1026
1023
|
self.window.core.idx.storage.remove_document(
|
|
1027
1024
|
id=idx,
|
|
@@ -1080,8 +1077,8 @@ class Indexing:
|
|
|
1080
1077
|
embed_model=embed_model,
|
|
1081
1078
|
) # get or create ctx index
|
|
1082
1079
|
|
|
1083
|
-
idx = "tmp:{}"
|
|
1084
|
-
self.window.core.idx.log("Indexing to context attachment index: {}..."
|
|
1080
|
+
idx = f"tmp:{index_path}" # tmp index id
|
|
1081
|
+
self.window.core.idx.log(f"Indexing to context attachment index: {idx}...")
|
|
1085
1082
|
|
|
1086
1083
|
doc_ids = []
|
|
1087
1084
|
if documents is None:
|
|
@@ -1118,8 +1115,8 @@ class Indexing:
|
|
|
1118
1115
|
llm, embed_model = self.window.core.idx.llm.get_service_context(model=model, stream=False)
|
|
1119
1116
|
index = self.window.core.idx.storage.get_ctx_idx(index_path, llm, embed_model) # get or create ctx index
|
|
1120
1117
|
|
|
1121
|
-
idx = "tmp:{}"
|
|
1122
|
-
self.window.core.idx.log("Indexing to context attachment index: {}..."
|
|
1118
|
+
idx = f"tmp:{index_path}" # tmp index id
|
|
1119
|
+
self.window.core.idx.log(f"Indexing to context attachment index: {idx}...")
|
|
1123
1120
|
|
|
1124
1121
|
web_type = self.get_webtype(url)
|
|
1125
1122
|
doc_ids = []
|
|
@@ -1153,7 +1150,7 @@ class Indexing:
|
|
|
1153
1150
|
if loader.is_supported_attachment(url):
|
|
1154
1151
|
type = id
|
|
1155
1152
|
break
|
|
1156
|
-
print("Selected web data loader: {}"
|
|
1153
|
+
print(f"Selected web data loader: {type}")
|
|
1157
1154
|
return type
|
|
1158
1155
|
|
|
1159
1156
|
def remove_attachment(
|
|
@@ -1188,7 +1185,7 @@ class Indexing:
|
|
|
1188
1185
|
time_since_last_call = now - self.last_call
|
|
1189
1186
|
if time_since_last_call < interval:
|
|
1190
1187
|
sleep_time = (interval - time_since_last_call).total_seconds()
|
|
1191
|
-
self.window.core.idx.log("RPM limit: sleep for {} seconds"
|
|
1188
|
+
self.window.core.idx.log(f"RPM limit: sleep for {sleep_time} seconds")
|
|
1192
1189
|
time.sleep(sleep_time)
|
|
1193
1190
|
self.last_call = now
|
|
1194
1191
|
|
pygpt_net/core/idx/response.py
CHANGED
|
@@ -6,28 +6,87 @@
|
|
|
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.
|
|
9
|
+
# Updated Date: 2025.08.21 07:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from typing import Any
|
|
13
|
+
|
|
13
14
|
from pygpt_net.item.model import ModelItem
|
|
14
15
|
from pygpt_net.item.ctx import CtxItem
|
|
15
16
|
|
|
16
17
|
class Response:
|
|
17
18
|
def __init__(self, window=None):
|
|
18
19
|
"""
|
|
19
|
-
Response
|
|
20
|
+
Response handler for processing responses from LLM or index.
|
|
20
21
|
|
|
21
22
|
:param window: Window instance
|
|
22
23
|
"""
|
|
23
24
|
self.window = window
|
|
24
25
|
|
|
26
|
+
def handle(
|
|
27
|
+
self,
|
|
28
|
+
ctx: CtxItem,
|
|
29
|
+
model: ModelItem,
|
|
30
|
+
llm,
|
|
31
|
+
response: Any,
|
|
32
|
+
cmd_enabled: bool,
|
|
33
|
+
use_react: bool,
|
|
34
|
+
use_index: bool,
|
|
35
|
+
stream: bool
|
|
36
|
+
) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Handle response based on the context, model, and response type.
|
|
39
|
+
|
|
40
|
+
:param ctx: Context item
|
|
41
|
+
:param model: Model item
|
|
42
|
+
:param llm: LLM instance
|
|
43
|
+
:param response: Response data
|
|
44
|
+
:param cmd_enabled: Tools enabled flag
|
|
45
|
+
:param use_react: Use REACT flag
|
|
46
|
+
:param use_index: Use index flag
|
|
47
|
+
:param stream: Stream enabled flag
|
|
48
|
+
"""
|
|
49
|
+
if cmd_enabled:
|
|
50
|
+
# tools enabled
|
|
51
|
+
if use_react:
|
|
52
|
+
self.from_react(ctx, model, response) # TOOLS + REACT, non-stream
|
|
53
|
+
else:
|
|
54
|
+
if stream:
|
|
55
|
+
if use_index:
|
|
56
|
+
self.from_index_stream(ctx, model, response) # INDEX + STREAM
|
|
57
|
+
else:
|
|
58
|
+
self.from_llm_stream(ctx, model, llm, response) # LLM + STREAM
|
|
59
|
+
else:
|
|
60
|
+
if use_index:
|
|
61
|
+
self.from_index(ctx, model, response) # TOOLS + INDEX
|
|
62
|
+
else:
|
|
63
|
+
self.from_llm(ctx, model, llm, response) # TOOLS + LLM
|
|
64
|
+
else:
|
|
65
|
+
# no tools
|
|
66
|
+
if stream:
|
|
67
|
+
if use_index:
|
|
68
|
+
self.from_index_stream(ctx, model, response) # INDEX + STREAM
|
|
69
|
+
else:
|
|
70
|
+
self.from_llm_stream(ctx, model, llm, response) # LLM + STREAM
|
|
71
|
+
else:
|
|
72
|
+
if use_index:
|
|
73
|
+
self.from_index(ctx, model, response) # INDEX
|
|
74
|
+
else:
|
|
75
|
+
self.from_llm(ctx, model, llm, response) # LLM
|
|
76
|
+
|
|
25
77
|
def from_react(
|
|
26
78
|
self,
|
|
27
79
|
ctx: CtxItem,
|
|
28
80
|
model: ModelItem,
|
|
29
81
|
response: Any
|
|
30
82
|
) -> None:
|
|
83
|
+
"""
|
|
84
|
+
Handle response from REACT.
|
|
85
|
+
|
|
86
|
+
:param ctx: CtxItem
|
|
87
|
+
:param model: ModelItem
|
|
88
|
+
:param response: Response data
|
|
89
|
+
"""
|
|
31
90
|
output = str(response)
|
|
32
91
|
if output is None:
|
|
33
92
|
output = ""
|
|
@@ -39,6 +98,13 @@ class Response:
|
|
|
39
98
|
model: ModelItem,
|
|
40
99
|
response: Any
|
|
41
100
|
) -> None:
|
|
101
|
+
"""
|
|
102
|
+
Handle response from index.
|
|
103
|
+
|
|
104
|
+
:param ctx: CtxItem
|
|
105
|
+
:param model: ModelItem
|
|
106
|
+
:param response: Response data
|
|
107
|
+
"""
|
|
42
108
|
output = str(response.response)
|
|
43
109
|
if output is None:
|
|
44
110
|
output = ""
|
|
@@ -51,6 +117,14 @@ class Response:
|
|
|
51
117
|
llm,
|
|
52
118
|
response: Any
|
|
53
119
|
) -> None:
|
|
120
|
+
"""
|
|
121
|
+
Handle response from LLM.
|
|
122
|
+
|
|
123
|
+
:param ctx: CtxItem
|
|
124
|
+
:param model: ModelItem
|
|
125
|
+
:param llm: LLM instance
|
|
126
|
+
:param response: Response data
|
|
127
|
+
"""
|
|
54
128
|
output = response.message.content
|
|
55
129
|
tool_calls = llm.get_tool_calls_from_response(
|
|
56
130
|
response,
|
|
@@ -67,6 +141,13 @@ class Response:
|
|
|
67
141
|
model: ModelItem,
|
|
68
142
|
response: Any
|
|
69
143
|
) -> None:
|
|
144
|
+
"""
|
|
145
|
+
Handle streaming response from index.
|
|
146
|
+
|
|
147
|
+
:param ctx: CtxItem
|
|
148
|
+
:param model: ModelItem
|
|
149
|
+
:param response: Response data
|
|
150
|
+
"""
|
|
70
151
|
ctx.stream = response.response_gen
|
|
71
152
|
ctx.set_output("", "")
|
|
72
153
|
|
|
@@ -77,5 +158,13 @@ class Response:
|
|
|
77
158
|
llm,
|
|
78
159
|
response: Any
|
|
79
160
|
) -> None:
|
|
161
|
+
"""
|
|
162
|
+
Handle streaming response from LLM.
|
|
163
|
+
|
|
164
|
+
:param ctx: CtxItem
|
|
165
|
+
:param model: ModelItem
|
|
166
|
+
:param llm: LLM instance
|
|
167
|
+
:param response: Response data
|
|
168
|
+
"""
|
|
80
169
|
ctx.stream = response # chunk is in response.delta
|
|
81
170
|
ctx.set_output("", "")
|
pygpt_net/core/idx/worker.py
CHANGED
|
@@ -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.
|
|
9
|
+
# Updated Date: 2025.08.21 07:00:00 #
|
|
10
10
|
# ================================================== #
|
|
11
11
|
|
|
12
12
|
from PySide6.QtCore import QObject, Signal, QRunnable, Slot
|
|
@@ -42,12 +42,7 @@ class IndexWorker(QRunnable):
|
|
|
42
42
|
|
|
43
43
|
# log
|
|
44
44
|
self.log("Indexing data...")
|
|
45
|
-
self.log("Idx: {}, type: {}, content: {}, from_ts: {}"
|
|
46
|
-
self.idx,
|
|
47
|
-
self.type,
|
|
48
|
-
self.content,
|
|
49
|
-
self.from_ts,
|
|
50
|
-
))
|
|
45
|
+
self.log(f"Idx: {self.idx}, type: {self.type}, content: {self.content}, from_ts: {self.from_ts}")
|
|
51
46
|
|
|
52
47
|
# execute indexing
|
|
53
48
|
if self.type == "file":
|
|
@@ -126,5 +121,5 @@ class IndexWorker(QRunnable):
|
|
|
126
121
|
is_log = True
|
|
127
122
|
self.window.core.debug.info(msg, not is_log)
|
|
128
123
|
if is_log:
|
|
129
|
-
print("[
|
|
124
|
+
print(f"[LlamaIndex] {msg}")
|
|
130
125
|
self.window.idx_logger_message.emit(msg)
|
|
@@ -262,7 +262,22 @@ class Body:
|
|
|
262
262
|
element.classList.remove('empty_list');
|
|
263
263
|
element.insertAdjacentHTML('beforeend', content);
|
|
264
264
|
highlightCode(true, element);
|
|
265
|
-
|
|
265
|
+
scrollToBottom(false); // without schedule
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function replaceNodes(content) {
|
|
269
|
+
if (DEBUG_MODE) {
|
|
270
|
+
log("REPLACE NODES: {" + content + "}");
|
|
271
|
+
}
|
|
272
|
+
clearStreamBefore();
|
|
273
|
+
prevScroll = 0;
|
|
274
|
+
const element = els.nodes || document.getElementById('_nodes_');
|
|
275
|
+
if (element) {
|
|
276
|
+
element.classList.remove('empty_list');
|
|
277
|
+
element.replaceChildren();
|
|
278
|
+
element.insertAdjacentHTML('beforeend', content);
|
|
279
|
+
highlightCode(true, element);
|
|
280
|
+
scrollToBottom(false); // without schedule
|
|
266
281
|
}
|
|
267
282
|
}
|
|
268
283
|
function clean() {
|
|
@@ -275,6 +290,7 @@ class Body:
|
|
|
275
290
|
}
|
|
276
291
|
resetEphemeralDomRefs();
|
|
277
292
|
els = {};
|
|
293
|
+
/*
|
|
278
294
|
try {
|
|
279
295
|
if (window.gc) {
|
|
280
296
|
window.gc();
|
|
@@ -282,6 +298,7 @@ class Body:
|
|
|
282
298
|
} catch (e) {
|
|
283
299
|
// gc not available
|
|
284
300
|
}
|
|
301
|
+
*/
|
|
285
302
|
}
|
|
286
303
|
function appendExtra(id, content) {
|
|
287
304
|
hideTips();
|