kssrag 0.2.2__py3-none-any.whl → 0.2.3__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.
- kssrag/core/agents.py +149 -106
- kssrag/server.py +1 -1
- {kssrag-0.2.2.dist-info → kssrag-0.2.3.dist-info}/METADATA +2 -2
- {kssrag-0.2.2.dist-info → kssrag-0.2.3.dist-info}/RECORD +7 -7
- {kssrag-0.2.2.dist-info → kssrag-0.2.3.dist-info}/WHEEL +1 -1
- {kssrag-0.2.2.dist-info → kssrag-0.2.3.dist-info}/entry_points.txt +0 -0
- {kssrag-0.2.2.dist-info → kssrag-0.2.3.dist-info}/top_level.txt +0 -0
kssrag/core/agents.py
CHANGED
|
@@ -21,13 +21,36 @@ class RAGAgent:
|
|
|
21
21
|
if not any(msg.get("role") == "system" for msg in self.conversation):
|
|
22
22
|
self.add_message("system", self.system_prompt)
|
|
23
23
|
|
|
24
|
+
# def add_message(self, role: str, content: str):
|
|
25
|
+
# """Add a message to the conversation history"""
|
|
26
|
+
# self.conversation.append({"role": role, "content": content})
|
|
27
|
+
|
|
28
|
+
# # Keep conversation manageable (last 15 messages)
|
|
29
|
+
# if len(self.conversation) > 15:
|
|
30
|
+
# self._smart_trim_conversation()
|
|
31
|
+
|
|
24
32
|
def add_message(self, role: str, content: str):
|
|
25
|
-
"""Add a message to the conversation history"""
|
|
33
|
+
"""Add a message to the conversation history (with simple dedupe for assistant)."""
|
|
34
|
+
content = content.strip()
|
|
35
|
+
# Prevent adding empty messages
|
|
36
|
+
if not content:
|
|
37
|
+
logger.info("Attempted to add empty message – ignored.")
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
# If last message is identical assistant content, skip to avoid duplicates
|
|
41
|
+
if self.conversation:
|
|
42
|
+
last = self.conversation[-1]
|
|
43
|
+
if role == "assistant" and last.get("role") == "assistant":
|
|
44
|
+
if last.get("content", "").strip() == content:
|
|
45
|
+
logger.info("Duplicate assistant message suppressed.")
|
|
46
|
+
return
|
|
47
|
+
|
|
26
48
|
self.conversation.append({"role": role, "content": content})
|
|
27
|
-
|
|
49
|
+
|
|
28
50
|
# Keep conversation manageable (last 15 messages)
|
|
29
51
|
if len(self.conversation) > 15:
|
|
30
52
|
self._smart_trim_conversation()
|
|
53
|
+
|
|
31
54
|
|
|
32
55
|
def _smart_trim_conversation(self):
|
|
33
56
|
"""Trim conversation while preserving system message and recent exchanges"""
|
|
@@ -123,136 +146,140 @@ class RAGAgent:
|
|
|
123
146
|
- Focus on user preferences, names, important context
|
|
124
147
|
|
|
125
148
|
The summary will be automatically hidden from the user."""
|
|
126
|
-
|
|
149
|
+
|
|
127
150
|
# def _extract_summary_and_response(self, full_response: str) -> tuple[str, Optional[str]]:
|
|
128
151
|
# """Extract summary from response and return clean user response - handles partial markers"""
|
|
152
|
+
# # Keep original markers for backward compatibility
|
|
129
153
|
# summary_start = "[SUMMARY_START]"
|
|
130
154
|
# summary_end = "[SUMMARY_END]"
|
|
131
155
|
|
|
132
|
-
# #
|
|
133
|
-
#
|
|
134
|
-
|
|
135
|
-
#
|
|
156
|
+
# # NEW: Normalize the response first (improvement from new version)
|
|
157
|
+
# normalized = full_response.replace('\n', ' ').replace('\r', ' ').strip()
|
|
158
|
+
|
|
159
|
+
# # Check if we have complete markers - KEEP original logic but use normalized
|
|
160
|
+
# if summary_start in normalized and summary_end in normalized:
|
|
161
|
+
# start_idx = normalized.find(summary_start) + len(summary_start)
|
|
162
|
+
# end_idx = normalized.find(summary_end)
|
|
136
163
|
|
|
137
|
-
# summary =
|
|
138
|
-
# user_response =
|
|
164
|
+
# summary = normalized[start_idx:end_idx].strip()
|
|
165
|
+
# user_response = normalized[:normalized.find(summary_start)].strip()
|
|
139
166
|
|
|
140
167
|
# logger.info(f"✅ SUCCESS: Summary extracted and separated from user response")
|
|
141
168
|
# logger.info(f"User response length: {len(user_response)} chars")
|
|
142
169
|
# logger.info(f"Summary extracted: '{summary}'")
|
|
143
|
-
# return user_response, summary
|
|
144
|
-
|
|
145
|
-
# # Check if we have partial markers (common in streaming)
|
|
146
|
-
# elif summary_start in full_response:
|
|
147
|
-
# # We have start marker but no end marker - extract what we can
|
|
148
|
-
# start_idx = full_response.find(summary_start) + len(summary_start)
|
|
149
|
-
# potential_summary = full_response[start_idx:].strip()
|
|
150
170
|
|
|
151
|
-
# #
|
|
152
|
-
# if
|
|
153
|
-
#
|
|
154
|
-
#
|
|
155
|
-
# user_response = full_response[:full_response.find(summary_start)].strip()
|
|
171
|
+
# # NEW: Add validation from improved version
|
|
172
|
+
# if not summary or len(summary) < 5:
|
|
173
|
+
# logger.info("❌ Summary too short, returning full response")
|
|
174
|
+
# return full_response.strip(), None
|
|
156
175
|
|
|
157
|
-
#
|
|
158
|
-
# logger.info(f"⚠️ Partial summary extracted (missing end marker): '{cleaned_summary}'")
|
|
159
|
-
# return user_response, cleaned_summary
|
|
160
|
-
|
|
161
|
-
# logger.info("❌ Incomplete summary markers found")
|
|
162
|
-
# return full_response, None
|
|
163
|
-
|
|
164
|
-
# logger.info("❌ No summary markers found, returning full response")
|
|
165
|
-
# logger.info(f"Full response length: {len(full_response)} chars")
|
|
166
|
-
# return full_response, None
|
|
176
|
+
# return user_response, summary
|
|
167
177
|
|
|
168
178
|
def _extract_summary_and_response(self, full_response: str) -> tuple[str, Optional[str]]:
|
|
169
|
-
"""Extract summary from response and return clean user response
|
|
170
|
-
|
|
179
|
+
"""Extract summary from response and return clean user response."""
|
|
180
|
+
|
|
181
|
+
if not full_response:
|
|
182
|
+
return "", None
|
|
183
|
+
|
|
171
184
|
summary_start = "[SUMMARY_START]"
|
|
172
185
|
summary_end = "[SUMMARY_END]"
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
normalized =
|
|
176
|
-
|
|
177
|
-
#
|
|
186
|
+
|
|
187
|
+
original = full_response
|
|
188
|
+
normalized = original.replace('\r\n', '\n').replace('\r', '\n')
|
|
189
|
+
|
|
190
|
+
# Case 1: Complete markers
|
|
178
191
|
if summary_start in normalized and summary_end in normalized:
|
|
179
192
|
start_idx = normalized.find(summary_start) + len(summary_start)
|
|
180
193
|
end_idx = normalized.find(summary_end)
|
|
181
|
-
|
|
182
194
|
summary = normalized[start_idx:end_idx].strip()
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
logger.info(f"User response length: {len(user_response)} chars")
|
|
187
|
-
logger.info(f"Summary extracted: '{summary}'")
|
|
188
|
-
|
|
189
|
-
# NEW: Add validation from improved version
|
|
195
|
+
|
|
196
|
+
user_response = original.split(summary_start)[0].strip()
|
|
197
|
+
|
|
190
198
|
if not summary or len(summary) < 5:
|
|
191
|
-
logger.info("
|
|
192
|
-
return
|
|
193
|
-
|
|
199
|
+
logger.info("Summary too short or invalid")
|
|
200
|
+
return original.strip(), None
|
|
201
|
+
|
|
202
|
+
logger.info("Summary extracted successfully")
|
|
194
203
|
return user_response, summary
|
|
195
|
-
|
|
196
|
-
#
|
|
197
|
-
|
|
198
|
-
# We have start marker but no end marker - extract what we can
|
|
204
|
+
|
|
205
|
+
# Case 2: Partial marker (start only)
|
|
206
|
+
if summary_start in normalized:
|
|
199
207
|
start_idx = normalized.find(summary_start) + len(summary_start)
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
user_response
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return user_response, cleaned_summary
|
|
222
|
-
|
|
223
|
-
logger.info("❌ Incomplete summary markers found")
|
|
224
|
-
return full_response.strip(), None # NEW: strip for consistency
|
|
225
|
-
|
|
208
|
+
potential = normalized[start_idx:start_idx + 200].strip()
|
|
209
|
+
|
|
210
|
+
cleaned_summary = (
|
|
211
|
+
potential
|
|
212
|
+
.split('[SUMMARY_')[0]
|
|
213
|
+
.split('[SUMMARY')[0]
|
|
214
|
+
.split('[')[0]
|
|
215
|
+
.strip()
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
user_response = original.split(summary_start)[0].strip()
|
|
219
|
+
|
|
220
|
+
if cleaned_summary and len(cleaned_summary) >= 10:
|
|
221
|
+
logger.info("Partial summary extracted")
|
|
222
|
+
return user_response, cleaned_summary
|
|
223
|
+
|
|
224
|
+
logger.info("Partial summary invalid")
|
|
225
|
+
return original.strip(), None
|
|
226
|
+
|
|
227
|
+
# Case 3: No markers at all
|
|
228
|
+
logger.info("No summary markers found")
|
|
226
229
|
# No markers found - KEEP original but with normalization
|
|
227
|
-
logger.info("
|
|
228
|
-
logger.info(f"Full response length: {len(
|
|
229
|
-
return
|
|
230
|
+
# logger.info(" No summary markers found, returning full response")
|
|
231
|
+
logger.info(f"Full response length: {len(original)} chars")
|
|
232
|
+
return original.strip(), None
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
# return full_response.strip(), None # NEW: strip for consistency
|
|
230
237
|
|
|
238
|
+
# def _add_conversation_summary(self, new_summary: str):
|
|
239
|
+
# """Add a new discrete conversation summary"""
|
|
240
|
+
# if not new_summary or new_summary.lower() == "none":
|
|
241
|
+
# logger.info("🔄 No summary to add (empty or 'none')")
|
|
242
|
+
# return
|
|
243
|
+
|
|
244
|
+
# # Add as a new discrete summary
|
|
245
|
+
# self.conversation_summaries.append(new_summary)
|
|
246
|
+
# logger.info(f"📝 ADDED Summary #{len(self.conversation_summaries)}: '{new_summary}'")
|
|
247
|
+
|
|
248
|
+
# # Keep only recent summaries (last 7)
|
|
249
|
+
# if len(self.conversation_summaries) > 7:
|
|
250
|
+
# self.conversation_summaries = self.conversation_summaries[-7:]
|
|
251
|
+
# removed = self.conversation_summaries.pop(0)
|
|
252
|
+
# logger.info(f"🗑️ DROPPED Oldest summary: '{removed}'")
|
|
253
|
+
# logger.info(f"📊 Summary count maintained at {len(self.conversation_summaries)}")
|
|
254
|
+
# logger.info(f"Added conversation summary #{len(self.conversation_summaries)}: {new_summary}")
|
|
231
255
|
def _add_conversation_summary(self, new_summary: str):
|
|
232
256
|
"""Add a new discrete conversation summary"""
|
|
233
257
|
if not new_summary or new_summary.lower() == "none":
|
|
234
|
-
logger.info("
|
|
258
|
+
logger.info(" No summary to add (empty or 'none')")
|
|
235
259
|
return
|
|
236
|
-
|
|
237
|
-
|
|
260
|
+
|
|
261
|
+
new_summary = new_summary.strip()
|
|
262
|
+
if not new_summary:
|
|
263
|
+
logger.info(" No summary to add after strip")
|
|
264
|
+
return
|
|
265
|
+
|
|
266
|
+
# Append new summary
|
|
238
267
|
self.conversation_summaries.append(new_summary)
|
|
239
|
-
logger.info(f"
|
|
268
|
+
logger.info(f" ADDED Summary #{len(self.conversation_summaries)}: '{new_summary}'")
|
|
240
269
|
|
|
241
270
|
# Keep only recent summaries (last 7)
|
|
242
271
|
if len(self.conversation_summaries) > 7:
|
|
243
272
|
self.conversation_summaries = self.conversation_summaries[-7:]
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
logger.info(f"📊 Summary count maintained at {len(self.conversation_summaries)}")
|
|
247
|
-
logger.info(f"Added conversation summary #{len(self.conversation_summaries)}: {new_summary}")
|
|
273
|
+
logger.info(f" Summary count trimmed to {len(self.conversation_summaries)}")
|
|
274
|
+
|
|
248
275
|
|
|
249
276
|
def query(self, question: str, top_k: int = 5, include_context: bool = True) -> str:
|
|
250
277
|
"""Process a query with stealth conversation summarization"""
|
|
251
278
|
try:
|
|
252
279
|
# Retrieve relevant context
|
|
253
|
-
logger.info(f"
|
|
280
|
+
logger.info(f" QUERY START: '{question}' (top_k: {top_k})")
|
|
254
281
|
context_docs = self.retriever.retrieve(question, top_k)
|
|
255
|
-
logger.info(f"
|
|
282
|
+
logger.info(f" Retrieved {len(context_docs)} context documents")
|
|
256
283
|
|
|
257
284
|
if not context_docs and include_context:
|
|
258
285
|
logger.warning(f"No context found for query: {question}")
|
|
@@ -266,7 +293,7 @@ class RAGAgent:
|
|
|
266
293
|
|
|
267
294
|
# Generate response
|
|
268
295
|
full_response = self.llm.predict(messages)
|
|
269
|
-
logger.info(f"
|
|
296
|
+
logger.info(f" LLM response received: {len(full_response)} chars")
|
|
270
297
|
|
|
271
298
|
# Extract summary and clean response
|
|
272
299
|
user_response, conversation_summary = self._extract_summary_and_response(full_response)
|
|
@@ -281,12 +308,12 @@ class RAGAgent:
|
|
|
281
308
|
# Add assistant response to conversation (clean version only)
|
|
282
309
|
self.add_message("assistant", user_response)
|
|
283
310
|
|
|
284
|
-
logger.info(f"
|
|
311
|
+
logger.info(f" Final user response: {len(user_response)} chars")
|
|
285
312
|
return user_response
|
|
286
313
|
|
|
287
314
|
except Exception as e:
|
|
288
315
|
logger.error(f"Error processing query: {str(e)}")
|
|
289
|
-
# logger.error(f"
|
|
316
|
+
# logger.error(f" QUERY FAILED: {str(e)}")
|
|
290
317
|
return "I encountered an issue processing your query. Please try again."
|
|
291
318
|
|
|
292
319
|
def query_stream(self, question: str, top_k: int = 5) -> Generator[str, None, None]:
|
|
@@ -294,7 +321,7 @@ class RAGAgent:
|
|
|
294
321
|
Professional-grade streaming with multiple fallback strategies
|
|
295
322
|
"""
|
|
296
323
|
try:
|
|
297
|
-
logger.info(f"
|
|
324
|
+
logger.info(f" STREAMING QUERY START: '{question}'")
|
|
298
325
|
|
|
299
326
|
# Strategy 1: Try true streaming first
|
|
300
327
|
if hasattr(self.llm, 'predict_stream'):
|
|
@@ -305,11 +332,11 @@ class RAGAgent:
|
|
|
305
332
|
logger.warning(f"Streaming failed, falling back: {stream_error}")
|
|
306
333
|
|
|
307
334
|
# Strategy 2: Fallback to simulated streaming
|
|
308
|
-
logger.info("
|
|
335
|
+
logger.info(" Falling back to simulated streaming")
|
|
309
336
|
yield from self._simulated_streaming(question, top_k)
|
|
310
337
|
|
|
311
338
|
except Exception as e:
|
|
312
|
-
logger.error(f"
|
|
339
|
+
logger.error(f" ALL STREAMING STRATEGIES FAILED: {str(e)}")
|
|
313
340
|
yield f"Error: {str(e)}"
|
|
314
341
|
|
|
315
342
|
def _stream_with_summary_protection(self, question: str, top_k: int) -> Generator[str, None, None]:
|
|
@@ -328,7 +355,7 @@ class RAGAgent:
|
|
|
328
355
|
# Check for summary markers
|
|
329
356
|
if any(marker in chunk for marker in ['[SUMMARY', 'SUMMARY_']):
|
|
330
357
|
if not summary_started:
|
|
331
|
-
logger.info("
|
|
358
|
+
logger.info(" Summary markers detected - cutting stream")
|
|
332
359
|
summary_started = True
|
|
333
360
|
clean_part = self._extract_clean_content(buffer)
|
|
334
361
|
if clean_part:
|
|
@@ -346,15 +373,31 @@ class RAGAgent:
|
|
|
346
373
|
logger.error(f"Streaming error: {e}")
|
|
347
374
|
raise # Re-raise to trigger fallback
|
|
348
375
|
|
|
376
|
+
# def _process_complete_response(self, full_response: str):
|
|
377
|
+
# """Process complete response and extract summary"""
|
|
378
|
+
# user_response, conversation_summary = self._extract_summary_and_response(full_response)
|
|
379
|
+
|
|
380
|
+
# if conversation_summary:
|
|
381
|
+
# logger.info(f" Summary extracted: '{conversation_summary}'")
|
|
382
|
+
# self._add_conversation_summary(conversation_summary)
|
|
383
|
+
|
|
384
|
+
# self.add_message("assistant", user_response)
|
|
349
385
|
def _process_complete_response(self, full_response: str):
|
|
350
386
|
"""Process complete response and extract summary"""
|
|
351
387
|
user_response, conversation_summary = self._extract_summary_and_response(full_response)
|
|
352
|
-
|
|
388
|
+
|
|
353
389
|
if conversation_summary:
|
|
354
|
-
logger.info(f"
|
|
390
|
+
logger.info(f" Summary extracted: '{conversation_summary}'")
|
|
355
391
|
self._add_conversation_summary(conversation_summary)
|
|
356
|
-
|
|
357
|
-
|
|
392
|
+
|
|
393
|
+
# extra guard: only add assistant message if different from last assistant message
|
|
394
|
+
if user_response:
|
|
395
|
+
last = self.conversation[-1] if self.conversation else None
|
|
396
|
+
if not (last and last.get("role") == "assistant" and last.get("content", "").strip() == user_response.strip()):
|
|
397
|
+
self.add_message("assistant", user_response)
|
|
398
|
+
else:
|
|
399
|
+
logger.info("Skipped adding duplicate assistant message in _process_complete_response.")
|
|
400
|
+
|
|
358
401
|
|
|
359
402
|
def _simulated_streaming(self, question: str, top_k: int) -> Generator[str, None, None]:
|
|
360
403
|
"""Simulated streaming that guarantees no summary leakage"""
|
|
@@ -369,14 +412,14 @@ class RAGAgent:
|
|
|
369
412
|
user_response, conversation_summary = self._extract_summary_and_response(complete_response)
|
|
370
413
|
|
|
371
414
|
if conversation_summary:
|
|
372
|
-
logger.info(f"
|
|
415
|
+
logger.info(f" Summary extracted: '{conversation_summary}'")
|
|
373
416
|
self._add_conversation_summary(conversation_summary)
|
|
374
417
|
|
|
375
418
|
self.add_message("assistant", user_response)
|
|
376
419
|
|
|
377
420
|
# Simulate streaming (smaller chunks for better UX)
|
|
378
421
|
chunk_size = 2 # Even smaller chunks for smoother streaming
|
|
379
|
-
for i in range(0, len(user_response),
|
|
422
|
+
for i in range(0, len(user_response), chunk_add_conversation_summary_size):
|
|
380
423
|
yield user_response[i:i+chunk_size]
|
|
381
424
|
import time
|
|
382
425
|
time.sleep(0.02) # Slightly longer delay for readability
|
|
@@ -403,5 +446,5 @@ class RAGAgent:
|
|
|
403
446
|
"message_count": len(self.conversation),
|
|
404
447
|
"recent_messages": [f"{msg['role']}: {msg['content'][:50]}..." for msg in self.conversation[-3:]]
|
|
405
448
|
}
|
|
406
|
-
logger.info(f"
|
|
449
|
+
logger.info(f" Context snapshot: {context}")
|
|
407
450
|
return context
|
kssrag/server.py
CHANGED
|
@@ -125,7 +125,7 @@ def create_app(rag_agent: RAGAgent, server_config: Optional[ServerConfig] = None
|
|
|
125
125
|
|
|
126
126
|
return StreamingResponse(
|
|
127
127
|
generate(),
|
|
128
|
-
media_type="text/
|
|
128
|
+
media_type="text/event-stream",
|
|
129
129
|
headers={
|
|
130
130
|
"Cache-Control": "no-cache",
|
|
131
131
|
"Connection": "keep-alive",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kssrag
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: A flexible Retrieval-Augmented Generation framework by Ksschkw
|
|
5
5
|
Home-page: https://github.com/Ksschkw/kssrag
|
|
6
6
|
Author: Ksschkw
|
|
@@ -85,7 +85,7 @@ Dynamic: summary
|
|
|
85
85
|
|
|
86
86
|

|
|
87
87
|

|
|
88
|
-

|
|
89
89
|

|
|
90
90
|

|
|
91
91
|
|
|
@@ -2,9 +2,9 @@ kssrag/__init__.py,sha256=N1XfR8IRKtEJAzcOVyHnKXtgx-ztlrSFtFwiVkGbAX8,2041
|
|
|
2
2
|
kssrag/cli.py,sha256=9AbtUEV9X63bhRj4EU-eHhud8iPM7LJAGSbu_IPlMUE,9703
|
|
3
3
|
kssrag/config.py,sha256=zd978GZQ66TlLZnk9yP7uvoXoWD89BS8VHi7w_yGXrM,6529
|
|
4
4
|
kssrag/kssrag.py,sha256=vy3oCHeHFAp_dJW0JjLbTxeEwCcwtXuOL_Ejmv0qz8Y,5251
|
|
5
|
-
kssrag/server.py,sha256=
|
|
5
|
+
kssrag/server.py,sha256=P2ztL-OF_bSo5xaMB0Gpb4w1RWEEL-YAyOqC1EMZdQc,6241
|
|
6
6
|
kssrag/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
kssrag/core/agents.py,sha256=
|
|
7
|
+
kssrag/core/agents.py,sha256=M5NnJbypk5HW4CxI2MdGQ271Q4teFT5NUUiEZf7JqQM,21115
|
|
8
8
|
kssrag/core/chunkers.py,sha256=HmWL3y2DhhobV5zIlIdZP2KK2N7TASqeirPqmc3_inI,7324
|
|
9
9
|
kssrag/core/retrievers.py,sha256=1e9c7ukUD4pFSVasOMTXSKoz_rapXQTl-FrSHK6Osqg,3037
|
|
10
10
|
kssrag/core/vectorstores.py,sha256=H8hTpjc6hAFMhqAO2Cjq-Jp6xrJhsJKiRN9qxb_-6XM,21003
|
|
@@ -26,8 +26,8 @@ tests/test_integration.py,sha256=TY7MrTcAiu1KG4MlgIC7VVlzUTnOoqp9pieK8rhBNrg,105
|
|
|
26
26
|
tests/test_ocr.py,sha256=PoGKLNISpAwaoPvGuS7qiOf6dsVnsFRFtYkG1WFi6TU,6202
|
|
27
27
|
tests/test_streaming.py,sha256=rMQ0w8_HQFFV0PbHDqQXRBqaNfbd3WqJVNT2hKVbsqw,1442
|
|
28
28
|
tests/test_vectorstores.py,sha256=YOwI2bfqprzbq8ahIw4pbbbEOaKGcg-XPcLCO7WiLxE,1474
|
|
29
|
-
kssrag-0.2.
|
|
30
|
-
kssrag-0.2.
|
|
31
|
-
kssrag-0.2.
|
|
32
|
-
kssrag-0.2.
|
|
33
|
-
kssrag-0.2.
|
|
29
|
+
kssrag-0.2.3.dist-info/METADATA,sha256=APBpMOiuIASOLPv4kRTAeUilihNjVDPf-tO9GC8DDgo,24015
|
|
30
|
+
kssrag-0.2.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
31
|
+
kssrag-0.2.3.dist-info/entry_points.txt,sha256=g4tQj5YUqPK3Osb9BI85tsErxleSBUENiqlnX0fWK5M,43
|
|
32
|
+
kssrag-0.2.3.dist-info/top_level.txt,sha256=sO9LGINa0GEjLoHTtufpz01yM5SmeTw6M4zWHEF0R2s,13
|
|
33
|
+
kssrag-0.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|