knowledge-rag 4.1.0__tar.gz → 4.1.2__tar.gz
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.
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/PKG-INFO +5 -1
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/README.md +4 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/mcp_server/__init__.py +1 -1
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/mcp_server/server.py +12 -10
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/pyproject.toml +1 -1
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/.gitignore +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/LICENSE +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/config.example.yaml +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/mcp_server/config.py +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/mcp_server/guarded.py +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/mcp_server/ingestion.py +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/mcp_server/instance_lock.py +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/mcp_server/metrics.py +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/mcp_server/preflight.py +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/mcp_server/ratelimit.py +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/npm/README.md +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/presets/cybersecurity.yaml +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/presets/developer.yaml +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/presets/general.yaml +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/presets/research.yaml +0 -0
- {knowledge_rag-4.1.0 → knowledge_rag-4.1.2}/requirements.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: knowledge-rag
|
|
3
|
-
Version: 4.1.
|
|
3
|
+
Version: 4.1.2
|
|
4
4
|
Summary: Local RAG System for Claude Code — Hybrid search + Cross-encoder Reranking + 12 MCP Tools + 20 Format Parsers. Zero external servers.
|
|
5
5
|
Project-URL: Homepage, https://github.com/lyonzin/knowledge-rag
|
|
6
6
|
Project-URL: Repository, https://github.com/lyonzin/knowledge-rag
|
|
@@ -1409,6 +1409,10 @@ Common issues:
|
|
|
1409
1409
|
|
|
1410
1410
|
### Unreleased
|
|
1411
1411
|
|
|
1412
|
+
### v4.1.1 (2026-06-17)
|
|
1413
|
+
|
|
1414
|
+
- **FIX**: All `_indexed_docs` iterations now use `list()` snapshot, preventing `dictionary changed size during iteration` crash when FileWatcher modifies the index concurrently with MCP tool calls (affects `search_knowledge`, `search_similar`, `update_document`, `remove_document`, `evaluate_retrieval`, `list_categories`, `list_documents`)
|
|
1415
|
+
|
|
1412
1416
|
### v4.1.0 (2026-06-17)
|
|
1413
1417
|
|
|
1414
1418
|
- **Added:** `query_expansion_groups` config for symmetric synonym expansion (#92)
|
|
@@ -1369,6 +1369,10 @@ Common issues:
|
|
|
1369
1369
|
|
|
1370
1370
|
### Unreleased
|
|
1371
1371
|
|
|
1372
|
+
### v4.1.1 (2026-06-17)
|
|
1373
|
+
|
|
1374
|
+
- **FIX**: All `_indexed_docs` iterations now use `list()` snapshot, preventing `dictionary changed size during iteration` crash when FileWatcher modifies the index concurrently with MCP tool calls (affects `search_knowledge`, `search_similar`, `update_document`, `remove_document`, `evaluate_retrieval`, `list_categories`, `list_documents`)
|
|
1375
|
+
|
|
1372
1376
|
### v4.1.0 (2026-06-17)
|
|
1373
1377
|
|
|
1374
1378
|
- **Added:** `query_expansion_groups` config for symmetric synonym expansion (#92)
|
|
@@ -836,7 +836,9 @@ class DocumentWatcher(FileSystemEventHandler):
|
|
|
836
836
|
f"{stats['updated']} updated, {stats['deleted']} deleted"
|
|
837
837
|
)
|
|
838
838
|
except Exception as e:
|
|
839
|
-
|
|
839
|
+
import traceback as _tb
|
|
840
|
+
|
|
841
|
+
print(f"[WATCHER] Reindex failed: {e}\n{_tb.format_exc()}")
|
|
840
842
|
finally:
|
|
841
843
|
self._reindex_lock.release()
|
|
842
844
|
|
|
@@ -1050,7 +1052,7 @@ class KnowledgeOrchestrator:
|
|
|
1050
1052
|
print(f"[INDEX] Scanning {stats['total_files']} documents...")
|
|
1051
1053
|
|
|
1052
1054
|
path_to_docid: Dict[str, str] = {}
|
|
1053
|
-
for doc_id, info in self._indexed_docs.items():
|
|
1055
|
+
for doc_id, info in list(self._indexed_docs.items()):
|
|
1054
1056
|
path_to_docid[info.get("source", "")] = doc_id
|
|
1055
1057
|
|
|
1056
1058
|
current_paths = {str(doc.source) for doc in documents}
|
|
@@ -1516,7 +1518,7 @@ class KnowledgeOrchestrator:
|
|
|
1516
1518
|
|
|
1517
1519
|
# Find the doc_id from metadata lookup
|
|
1518
1520
|
doc_id = None
|
|
1519
|
-
for did, info in self._indexed_docs.items():
|
|
1521
|
+
for did, info in list(self._indexed_docs.items()):
|
|
1520
1522
|
stored = str(Path(info.get("source", "")).resolve())
|
|
1521
1523
|
if stored == str(Path(source).resolve()):
|
|
1522
1524
|
doc_id = did
|
|
@@ -1709,7 +1711,7 @@ class KnowledgeOrchestrator:
|
|
|
1709
1711
|
filepath_resolved = str(filepath.resolve())
|
|
1710
1712
|
|
|
1711
1713
|
doc_id = None
|
|
1712
|
-
for did, info in self._indexed_docs.items():
|
|
1714
|
+
for did, info in list(self._indexed_docs.items()):
|
|
1713
1715
|
stored = str(Path(info.get("source", "")).resolve())
|
|
1714
1716
|
if stored == filepath_resolved:
|
|
1715
1717
|
doc_id = did
|
|
@@ -1763,7 +1765,7 @@ class KnowledgeOrchestrator:
|
|
|
1763
1765
|
filepath_resolved = str(Path(filepath).resolve())
|
|
1764
1766
|
|
|
1765
1767
|
doc_id = None
|
|
1766
|
-
for did, info in self._indexed_docs.items():
|
|
1768
|
+
for did, info in list(self._indexed_docs.items()):
|
|
1767
1769
|
stored = str(Path(info.get("source", "")).resolve())
|
|
1768
1770
|
if stored == filepath_resolved:
|
|
1769
1771
|
doc_id = did
|
|
@@ -1824,7 +1826,7 @@ class KnowledgeOrchestrator:
|
|
|
1824
1826
|
filepath_resolved = str(Path(filepath).resolve())
|
|
1825
1827
|
|
|
1826
1828
|
doc_id = None
|
|
1827
|
-
for did, info in self._indexed_docs.items():
|
|
1829
|
+
for did, info in list(self._indexed_docs.items()):
|
|
1828
1830
|
stored = str(Path(info.get("source", "")).resolve())
|
|
1829
1831
|
if stored == filepath_resolved:
|
|
1830
1832
|
doc_id = did
|
|
@@ -1936,7 +1938,7 @@ class KnowledgeOrchestrator:
|
|
|
1936
1938
|
def list_categories(self) -> Dict[str, int]:
|
|
1937
1939
|
"""List all categories with document counts"""
|
|
1938
1940
|
categories = {}
|
|
1939
|
-
for doc_info in self._indexed_docs.values():
|
|
1941
|
+
for doc_info in list(self._indexed_docs.values()):
|
|
1940
1942
|
cat = doc_info.get("category", "unknown")
|
|
1941
1943
|
categories[cat] = categories.get(cat, 0) + 1
|
|
1942
1944
|
return categories
|
|
@@ -1944,7 +1946,7 @@ class KnowledgeOrchestrator:
|
|
|
1944
1946
|
def list_documents(self, category: Optional[str] = None) -> List[Dict[str, str]]:
|
|
1945
1947
|
"""List all indexed documents, optionally filtered by category"""
|
|
1946
1948
|
docs = []
|
|
1947
|
-
for doc_id, info in self._indexed_docs.items():
|
|
1949
|
+
for doc_id, info in list(self._indexed_docs.items()):
|
|
1948
1950
|
if category and info.get("category") != category:
|
|
1949
1951
|
continue
|
|
1950
1952
|
docs.append(
|
|
@@ -1986,7 +1988,8 @@ class KnowledgeOrchestrator:
|
|
|
1986
1988
|
def _save_metadata(self) -> None:
|
|
1987
1989
|
"""Save index metadata to disk"""
|
|
1988
1990
|
self._metadata_file.parent.mkdir(parents=True, exist_ok=True)
|
|
1989
|
-
|
|
1991
|
+
snapshot = dict(self._indexed_docs)
|
|
1992
|
+
self._metadata_file.write_text(json.dumps(snapshot, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
1990
1993
|
|
|
1991
1994
|
|
|
1992
1995
|
# =============================================================================
|
|
@@ -2445,7 +2448,6 @@ def evaluate_retrieval(test_cases: str) -> str:
|
|
|
2445
2448
|
|
|
2446
2449
|
orchestrator = get_orchestrator()
|
|
2447
2450
|
results = orchestrator.evaluate_retrieval(cases)
|
|
2448
|
-
|
|
2449
2451
|
return json.dumps({"status": "success", **results}, indent=2)
|
|
2450
2452
|
|
|
2451
2453
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "knowledge-rag"
|
|
7
|
-
version = "4.1.
|
|
7
|
+
version = "4.1.2"
|
|
8
8
|
description = "Local RAG System for Claude Code — Hybrid search + Cross-encoder Reranking + 12 MCP Tools + 20 Format Parsers. Zero external servers."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|