kssrag 0.1.0__py3-none-any.whl → 0.1.2__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/cli.py +17 -2
- kssrag/core/vectorstores.py +9 -0
- kssrag/utils/helpers.py +53 -23
- {kssrag-0.1.0.dist-info → kssrag-0.1.2.dist-info}/METADATA +6 -6
- {kssrag-0.1.0.dist-info → kssrag-0.1.2.dist-info}/RECORD +8 -9
- kssrag-0.1.0.dist-info/licenses/LICENSE +0 -0
- {kssrag-0.1.0.dist-info → kssrag-0.1.2.dist-info}/WHEEL +0 -0
- {kssrag-0.1.0.dist-info → kssrag-0.1.2.dist-info}/entry_points.txt +0 -0
- {kssrag-0.1.0.dist-info → kssrag-0.1.2.dist-info}/top_level.txt +0 -0
kssrag/cli.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import argparse
|
|
2
2
|
import sys
|
|
3
|
+
import os # Add this import if not already present
|
|
3
4
|
from .utils.document_loaders import load_document, load_json_documents
|
|
4
5
|
from .core.chunkers import TextChunker, JSONChunker, PDFChunker
|
|
5
6
|
from .core.vectorstores import BM25VectorStore, FAISSVectorStore, TFIDFVectorStore, HybridVectorStore, HybridOfflineVectorStore
|
|
@@ -24,6 +25,7 @@ def main():
|
|
|
24
25
|
choices=["bm25", "faiss", "tfidf", "hybrid_online", "hybrid_offline"],
|
|
25
26
|
help="Vector store type")
|
|
26
27
|
query_parser.add_argument("--top-k", type=int, default=config.TOP_K, help="Number of results to retrieve")
|
|
28
|
+
query_parser.add_argument("--system-prompt", type=str, help="Path to a file containing the system prompt or the prompt text itself")
|
|
27
29
|
|
|
28
30
|
# Server command
|
|
29
31
|
server_parser = subparsers.add_parser("server", help="Start the RAG API server")
|
|
@@ -35,12 +37,23 @@ def main():
|
|
|
35
37
|
help="Vector store type")
|
|
36
38
|
server_parser.add_argument("--port", type=int, default=config.SERVER_PORT, help="Port to run server on")
|
|
37
39
|
server_parser.add_argument("--host", type=str, default=config.SERVER_HOST, help="Host to run server on")
|
|
40
|
+
server_parser.add_argument("--system-prompt", type=str, help="Path to a file containing the system prompt or the prompt text itself")
|
|
38
41
|
|
|
39
42
|
args = parser.parse_args()
|
|
43
|
+
vector_store_type = args.vector_store if hasattr(args, 'vector_store') else config.VECTOR_STORE_TYPE
|
|
40
44
|
|
|
41
45
|
# Validate config
|
|
42
46
|
validate_config()
|
|
43
47
|
|
|
48
|
+
def load_system_prompt(prompt_arg):
|
|
49
|
+
"""Load system prompt from file or use as text"""
|
|
50
|
+
if not prompt_arg:
|
|
51
|
+
return None
|
|
52
|
+
if os.path.exists(prompt_arg):
|
|
53
|
+
with open(prompt_arg, 'r', encoding='utf-8') as f:
|
|
54
|
+
return f.read()
|
|
55
|
+
return prompt_arg
|
|
56
|
+
|
|
44
57
|
if args.command == "query":
|
|
45
58
|
# Load and process document
|
|
46
59
|
if args.format == "text":
|
|
@@ -78,7 +91,8 @@ def main():
|
|
|
78
91
|
# Create retriever and agent
|
|
79
92
|
retriever = SimpleRetriever(vector_store)
|
|
80
93
|
llm = OpenRouterLLM()
|
|
81
|
-
|
|
94
|
+
system_prompt = load_system_prompt(args.system_prompt)
|
|
95
|
+
agent = RAGAgent(retriever, llm, system_prompt=system_prompt)
|
|
82
96
|
|
|
83
97
|
# Query and print response
|
|
84
98
|
response = agent.query(args.query, top_k=args.top_k)
|
|
@@ -122,7 +136,8 @@ def main():
|
|
|
122
136
|
# Create retriever and agent
|
|
123
137
|
retriever = SimpleRetriever(vector_store)
|
|
124
138
|
llm = OpenRouterLLM()
|
|
125
|
-
|
|
139
|
+
system_prompt = load_system_prompt(args.system_prompt)
|
|
140
|
+
agent = RAGAgent(retriever, llm, system_prompt=system_prompt)
|
|
126
141
|
|
|
127
142
|
# Create and run server
|
|
128
143
|
from .server import create_app
|
kssrag/core/vectorstores.py
CHANGED
|
@@ -13,6 +13,13 @@ from typing import List, Dict, Any, Optional
|
|
|
13
13
|
from ..utils.helpers import logger
|
|
14
14
|
from ..config import config
|
|
15
15
|
|
|
16
|
+
FAISS_AVAILABLE = False
|
|
17
|
+
try:
|
|
18
|
+
import faiss
|
|
19
|
+
FAISS_AVAILABLE = True
|
|
20
|
+
except ImportError:
|
|
21
|
+
pass
|
|
22
|
+
|
|
16
23
|
class BaseVectorStore:
|
|
17
24
|
"""Base class for vector stores"""
|
|
18
25
|
|
|
@@ -104,6 +111,8 @@ class BM25VectorStore(BaseVectorStore):
|
|
|
104
111
|
import tempfile
|
|
105
112
|
class FAISSVectorStore(BaseVectorStore):
|
|
106
113
|
def __init__(self, persist_path: Optional[str] = None, model_name: Optional[str] = None):
|
|
114
|
+
if not FAISS_AVAILABLE:
|
|
115
|
+
raise ImportError("FAISS is not available. Please install it with 'pip install faiss-cpu' or use a different vector store.")
|
|
107
116
|
super().__init__(persist_path)
|
|
108
117
|
self.model_name = model_name or config.FAISS_MODEL_NAME
|
|
109
118
|
|
kssrag/utils/helpers.py
CHANGED
|
@@ -8,6 +8,54 @@ logging.basicConfig(
|
|
|
8
8
|
)
|
|
9
9
|
logger = logging.getLogger("KSSRAG")
|
|
10
10
|
|
|
11
|
+
|
|
12
|
+
def setup_faiss():
|
|
13
|
+
"""Handle FAISS initialization with proper error handling and fallbacks"""
|
|
14
|
+
faiss_available = False
|
|
15
|
+
faiss_avx_type = "standard"
|
|
16
|
+
|
|
17
|
+
# Only try to import FAISS if it's actually needed
|
|
18
|
+
from ..config import config
|
|
19
|
+
if config.VECTOR_STORE_TYPE in ["faiss", "hybrid_online"]:
|
|
20
|
+
try:
|
|
21
|
+
# Try different FAISS versions in order of preference
|
|
22
|
+
faiss_import_attempts = [
|
|
23
|
+
("AVX512-SPR", "faiss.swigfaiss_avx512_spr"),
|
|
24
|
+
("AVX512", "faiss.swigfaiss_avx512"),
|
|
25
|
+
("AVX2", "faiss.swigfaiss_avx2"),
|
|
26
|
+
("Standard", "faiss.swigfaiss")
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
for avx_type, import_path in faiss_import_attempts:
|
|
30
|
+
try:
|
|
31
|
+
logger.info(f"Loading faiss with {avx_type} support.")
|
|
32
|
+
# Dynamic import
|
|
33
|
+
import importlib
|
|
34
|
+
faiss_module = importlib.import_module(import_path)
|
|
35
|
+
# Make the FAISS symbols available globally
|
|
36
|
+
globals().update({name: getattr(faiss_module, name) for name in dir(faiss_module) if not name.startswith('_')})
|
|
37
|
+
|
|
38
|
+
faiss_available = True
|
|
39
|
+
faiss_avx_type = avx_type
|
|
40
|
+
logger.info(f"Successfully loaded faiss with {avx_type} support.")
|
|
41
|
+
break
|
|
42
|
+
|
|
43
|
+
except ImportError as e:
|
|
44
|
+
logger.info(f"Could not load library with {avx_type} support due to: {repr(e)}")
|
|
45
|
+
continue
|
|
46
|
+
|
|
47
|
+
if not faiss_available:
|
|
48
|
+
logger.warning("Could not load any FAISS version. FAISS-based vector stores will be disabled.")
|
|
49
|
+
|
|
50
|
+
except Exception as e:
|
|
51
|
+
logger.error(f"Failed to initialize FAISS: {str(e)}")
|
|
52
|
+
faiss_available = False
|
|
53
|
+
|
|
54
|
+
return faiss_available, faiss_avx_type
|
|
55
|
+
|
|
56
|
+
# Initialize FAISS only when needed
|
|
57
|
+
FAISS_AVAILABLE, FAISS_AVX_TYPE = setup_faiss()
|
|
58
|
+
|
|
11
59
|
# Your signature in the code
|
|
12
60
|
def kss_signature():
|
|
13
61
|
return "Built with HATE by Ksschkw (github.com/Ksschkw)"
|
|
@@ -19,8 +67,13 @@ def validate_config():
|
|
|
19
67
|
if not config.OPENROUTER_API_KEY:
|
|
20
68
|
logger.warning("OPENROUTER_API_KEY not set. LLM functionality will not work.")
|
|
21
69
|
|
|
70
|
+
if config.VECTOR_STORE_TYPE in ["faiss", "hybrid_online"] and not FAISS_AVAILABLE:
|
|
71
|
+
logger.warning(f"FAISS not available. Falling back to HYBRID_OFFLINE vector store.")
|
|
72
|
+
config.VECTOR_STORE_TYPE = "hybrid_offline"
|
|
73
|
+
|
|
22
74
|
return True
|
|
23
75
|
|
|
76
|
+
|
|
24
77
|
def import_custom_component(import_path: str):
|
|
25
78
|
"""Import a custom component from a string path"""
|
|
26
79
|
try:
|
|
@@ -30,26 +83,3 @@ def import_custom_component(import_path: str):
|
|
|
30
83
|
except (ImportError, AttributeError, ValueError) as e:
|
|
31
84
|
logger.error(f"Failed to import custom component {import_path}: {str(e)}")
|
|
32
85
|
raise
|
|
33
|
-
|
|
34
|
-
# import os
|
|
35
|
-
# import logging
|
|
36
|
-
# from .utils.helpers import logger
|
|
37
|
-
|
|
38
|
-
# def setup_faiss():
|
|
39
|
-
# """Handle FAISS initialization with proper error handling"""
|
|
40
|
-
# try:
|
|
41
|
-
# # Try to load with AVX2 support first
|
|
42
|
-
# logger.info("Loading faiss with AVX2 support.")
|
|
43
|
-
# from faiss.swigfaiss_avx2 import *
|
|
44
|
-
# logger.info("Successfully loaded faiss with AVX2 support.")
|
|
45
|
-
# return True
|
|
46
|
-
# except ImportError as e:
|
|
47
|
-
# logger.info(f"Could not load library with AVX2 support due to:\n{repr(e)}")
|
|
48
|
-
# logger.info("Falling back to standard FAISS without AVX2 support")
|
|
49
|
-
# try:
|
|
50
|
-
# from faiss.swigfaiss import *
|
|
51
|
-
# logger.info("Successfully loaded standard faiss.")
|
|
52
|
-
# return False
|
|
53
|
-
# except ImportError as e:
|
|
54
|
-
# logger.error(f"Failed to load any FAISS version: {repr(e)}")
|
|
55
|
-
# raise
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kssrag
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: A flexible Retrieval-Augmented Generation framework by Ksschkw
|
|
5
5
|
Home-page: https://github.com/Ksschkw/kssrag
|
|
6
6
|
Author: Ksschkw
|
|
@@ -22,7 +22,6 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
23
|
Requires-Python: >=3.8, <4
|
|
24
24
|
Description-Content-Type: text/markdown
|
|
25
|
-
License-File: LICENSE
|
|
26
25
|
Requires-Dist: fastapi>=0.104.0
|
|
27
26
|
Requires-Dist: uvicorn>=0.24.0
|
|
28
27
|
Requires-Dist: python-dotenv>=1.0.0
|
|
@@ -55,7 +54,6 @@ Dynamic: description
|
|
|
55
54
|
Dynamic: description-content-type
|
|
56
55
|
Dynamic: home-page
|
|
57
56
|
Dynamic: keywords
|
|
58
|
-
Dynamic: license-file
|
|
59
57
|
Dynamic: project-url
|
|
60
58
|
Dynamic: provides-extra
|
|
61
59
|
Dynamic: requires-dist
|
|
@@ -65,6 +63,8 @@ Dynamic: summary
|
|
|
65
63
|
# 🚀 KSS RAG - Knowledge Retrieval Augmented Generation Framework
|
|
66
64
|
|
|
67
65
|
> Built by [Ksschkw](https://github.com/Ksschkw)
|
|
66
|
+
\
|
|
67
|
+
> View at: [PyPi](https://pypi.org/project/kssrag/0.1.1/)
|
|
68
68
|
|
|
69
69
|

|
|
70
70
|

|
|
@@ -118,10 +118,10 @@ print(response)
|
|
|
118
118
|
export OPENROUTER_API_KEY="your_key_here"
|
|
119
119
|
|
|
120
120
|
# Query documents
|
|
121
|
-
python -m kssrag.cli query --file document.txt --query "Main ideas?"
|
|
121
|
+
python -m kssrag.cli query --file document.txt --system-prompt custom_prompt.txt(`or just insert plain text here in quotes`) --query "Main ideas?"
|
|
122
122
|
|
|
123
123
|
# Start API server
|
|
124
|
-
python -m kssrag.cli server --file document.txt --port 8000
|
|
124
|
+
python -m kssrag.cli server --file document.txt --system-prompt custom_prompt.txt(`or just insert plain text here in quotes`) --port 8000
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
## 🐳 Docker Deployment
|
|
@@ -265,7 +265,7 @@ python -m pytest --cov=kssrag tests/
|
|
|
265
265
|
**CLI Command Not Found**
|
|
266
266
|
```bash
|
|
267
267
|
# Use module syntax on Windows
|
|
268
|
-
python -m kssrag.cli query --file document.txt --query "Your question"
|
|
268
|
+
python -m kssrag.cli query --file document.txt --system-prompt custom_prompt.txt(`or just insert plain text here in quotes`) --query "Your question"
|
|
269
269
|
```
|
|
270
270
|
|
|
271
271
|
**FAISS Windows Issues**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
kssrag/__init__.py,sha256=N1XfR8IRKtEJAzcOVyHnKXtgx-ztlrSFtFwiVkGbAX8,2041
|
|
2
|
-
kssrag/cli.py,sha256=
|
|
2
|
+
kssrag/cli.py,sha256=2hdj9ZOsj-D40u_KW0pNOEE6khZZotlzkhGWJmBdxxg,7406
|
|
3
3
|
kssrag/config.py,sha256=vJUDJVfCoBy5QXw2YBGJBE6y_e5du4fq65EhT2pz3f0,6101
|
|
4
4
|
kssrag/kssrag.py,sha256=vy3oCHeHFAp_dJW0JjLbTxeEwCcwtXuOL_Ejmv0qz8Y,5251
|
|
5
5
|
kssrag/server.py,sha256=HR60UqVlimo9UrExv_zTh6faE4ueVuz-QKK7UtZxmAA,4029
|
|
@@ -7,20 +7,19 @@ kssrag/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
7
7
|
kssrag/core/agents.py,sha256=VRAeaj7x6u2xbxTGckAaSfMn0jeLafPuG0OHNEb3xLg,3273
|
|
8
8
|
kssrag/core/chunkers.py,sha256=om9f7FeAqvN4ppERrLq7WSwR4eQnQr-XziKAojFrtLE,3591
|
|
9
9
|
kssrag/core/retrievers.py,sha256=1e9c7ukUD4pFSVasOMTXSKoz_rapXQTl-FrSHK6Osqg,3037
|
|
10
|
-
kssrag/core/vectorstores.py,sha256=
|
|
10
|
+
kssrag/core/vectorstores.py,sha256=wdaukJJIPRcUDXKswzGrjebTCJtyGE8zBuflUuQxU3Q,17103
|
|
11
11
|
kssrag/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
kssrag/models/local_llms.py,sha256=IsthEwiNG1QcvHrTpQWdd1kZuHa4-0bfGTxHe8F3i2M,1178
|
|
13
13
|
kssrag/models/openrouter.py,sha256=x_I3eQBP_3xO4wRKWAbsBRzRE_Ur7kGtUuF9YGVSo5U,3716
|
|
14
14
|
kssrag/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
kssrag/utils/document_loaders.py,sha256=TLfi1-4YIyvuyIqiNBqLG9zl_FoT65s-zp37yqYSq38,1388
|
|
16
|
-
kssrag/utils/helpers.py,sha256=
|
|
16
|
+
kssrag/utils/helpers.py,sha256=C17A819OlbZ_7mNBlOig6gzfwXWJFbBSYaOm_AxCqt4,3331
|
|
17
17
|
kssrag/utils/preprocessors.py,sha256=_kbeZOWnbqbKKSBiyRP8QZAKx9uYMXgHfARcWBqC3JU,938
|
|
18
|
-
kssrag-0.1.0.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
18
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
19
|
tests/test_basic.py,sha256=JdBBRpP9wOo4BvvZTisidP40gGyK_azUoewJpoJaa5M,1275
|
|
21
20
|
tests/test_vectorstores.py,sha256=YOwI2bfqprzbq8ahIw4pbbbEOaKGcg-XPcLCO7WiLxE,1474
|
|
22
|
-
kssrag-0.1.
|
|
23
|
-
kssrag-0.1.
|
|
24
|
-
kssrag-0.1.
|
|
25
|
-
kssrag-0.1.
|
|
26
|
-
kssrag-0.1.
|
|
21
|
+
kssrag-0.1.2.dist-info/METADATA,sha256=4SeJGBdIRhBAEGXBxQ8wCG_8bMTaSM-nrPWikoiYsE0,10592
|
|
22
|
+
kssrag-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
kssrag-0.1.2.dist-info/entry_points.txt,sha256=g4tQj5YUqPK3Osb9BI85tsErxleSBUENiqlnX0fWK5M,43
|
|
24
|
+
kssrag-0.1.2.dist-info/top_level.txt,sha256=sO9LGINa0GEjLoHTtufpz01yM5SmeTw6M4zWHEF0R2s,13
|
|
25
|
+
kssrag-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|