ragx-cli 0.3.2__tar.gz → 0.3.3__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.
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/CHANGELOG.md +10 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/PKG-INFO +1 -1
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/pyproject.toml +1 -1
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/providers/st_reranker.py +31 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_providers.py +36 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/SKILL.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/api-cheatsheet.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/collection-management/python.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/collection-management/typescript.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/configuration.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/data-model.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/data-operations/python.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/data-operations/typescript.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/embedding.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/hybrid-search/python.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/hybrid-search/typescript.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/multimodal-search/python.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/multimodal-search/typescript.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/quick-start/python.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/quick-start/typescript.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/rag-system/python.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/rag-system/typescript.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/reranker.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/troubleshooting.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/vector-search/python.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.agents/skills/zvec/vector-search/typescript.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.github/workflows/publish.yml +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/.gitignore +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/AGENTS.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/CLAUDE.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/CONTRACTS-PHASE23.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/CONTRACTS.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/LICENSE +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/README.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/docs/feature-temporal-weighting.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/ragx-cli-plan.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/research/bge-m3-colbert-multi-vector-late-interaction-for-ragx-rerank-alternative-and-token-level-graph-edges.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/research/bge-m3-dense-embeddings-as-ragx-provider-multilingual-quality-and-threshold-calibration.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/research/bge-m3-dense-q8-vs-nomic-q4-benchmark-2026-07-12-worktree-eval-results.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/research/bge-m3-sparse-lexical-weights-hybrid-retrieval-leg-for-ragx-vs-sqlite-fts5-bm25.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/research/bge-m3-subchunk-edge-ablation-2026-07-13-ties-again-and-beta-zero-shortlist-mechanism.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/research/fine-grained-sub-chunk-edges-with-coarse-chunk-nodes-multi-granularity-graph-rag-literature-validation.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/research/subchunk-edge-ablation-2026-07-12-two-round-experiment-protocol-results-and-verdict.md +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/skills-lock.json +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/__init__.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/cli/__init__.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/cli/app.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/cli/detect.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/cli/eval_cmd.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/cli/init_prompt.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/cli/inspect_cmd.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/cli/output.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/cli/pipeline.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/__init__.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/chunking.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/communities.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/config.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/discovery.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/errors.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/eval.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/expansion.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/fusion.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/graph.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/indexer.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/models.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/query.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/scoring.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/store.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/traversal.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/core/vectors.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/providers/__init__.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/providers/base.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/providers/openai_compat.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/src/ragx/providers/registry.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/__init__.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/conftest.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_chunking.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_cli.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_communities.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_config_rc.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_discovery.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_eval.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_expansion.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_fusion.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_graph.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_inspect.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_integration.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_store.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_traversal.py +0 -0
- {ragx_cli-0.3.2 → ragx_cli-0.3.3}/tests/test_vectors.py +0 -0
|
@@ -4,6 +4,15 @@ All notable changes to `ragx-cli` are documented here. The format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
|
|
5
5
|
[Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.3.3] — 2026-07-15
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Early hint when the reranker model download stalls**: the huggingface_hub retry
|
|
12
|
+
loop inside the cross-encoder load can spin for minutes before failing. The first
|
|
13
|
+
retry warning now also prints a one-shot stderr pointer to the README's "Reranker on
|
|
14
|
+
restricted networks" section (manual copy, mirror, or `rerank.enabled false`).
|
|
15
|
+
|
|
7
16
|
## [0.3.2] — 2026-07-15
|
|
8
17
|
|
|
9
18
|
_0.3.1 was tagged but never published — its release workflow referenced a nonexistent
|
|
@@ -95,6 +104,7 @@ Initial release: Phases 0–3 of [the plan](ragx-cli-plan.md), built and validat
|
|
|
95
104
|
on stderr, exit codes `0` results / `1` empty / `2` error.
|
|
96
105
|
- MIT license; PyPI packaging as `ragx-cli` with trusted-publishing release workflow.
|
|
97
106
|
|
|
107
|
+
[0.3.3]: https://github.com/alber70g/ragx-cli/compare/v0.3.2...v0.3.3
|
|
98
108
|
[0.3.2]: https://github.com/alber70g/ragx-cli/compare/v0.3.0...v0.3.2
|
|
99
109
|
[0.3.0]: https://github.com/alber70g/ragx-cli/compare/v0.2.0...v0.3.0
|
|
100
110
|
[0.2.0]: https://github.com/alber70g/ragx-cli/compare/v0.1.1...v0.2.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ragx-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Similarity-graph RAG CLI: index a corpus into a chunk-level embedding graph and query it
|
|
5
5
|
Project-URL: Repository, https://github.com/alber70g/ragx-cli
|
|
6
6
|
Project-URL: Issues, https://github.com/alber70g/ragx-cli/issues
|
|
@@ -2,10 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import logging
|
|
6
|
+
import sys
|
|
5
7
|
from typing import Sequence
|
|
6
8
|
|
|
7
9
|
from ragx.core.errors import RagxError
|
|
8
10
|
|
|
11
|
+
_MANUAL_INSTALL_HINT = (
|
|
12
|
+
"downloading the reranker model from huggingface.co is failing — to install the "
|
|
13
|
+
"model manually, use a mirror, or disable reranking, see "
|
|
14
|
+
"https://github.com/alber70g/ragx-cli#reranker-on-restricted-networks-no-huggingfaceco"
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class _DownloadHintHandler(logging.Handler):
|
|
19
|
+
"""Emits the manual-install hint once, on the first huggingface_hub retry warning."""
|
|
20
|
+
|
|
21
|
+
def __init__(self) -> None:
|
|
22
|
+
super().__init__(level=logging.WARNING)
|
|
23
|
+
self._fired = False
|
|
24
|
+
|
|
25
|
+
def emit(self, record: logging.LogRecord) -> None:
|
|
26
|
+
if self._fired:
|
|
27
|
+
return
|
|
28
|
+
message = record.getMessage().lower()
|
|
29
|
+
if "retry" in message or "thrown while requesting" in message:
|
|
30
|
+
self._fired = True
|
|
31
|
+
# logging drops re-entrant calls made while a record is being
|
|
32
|
+
# handled, so the hint must go to stderr directly.
|
|
33
|
+
print(f"WARNING: {_MANUAL_INSTALL_HINT}", file=sys.stderr)
|
|
34
|
+
|
|
9
35
|
|
|
10
36
|
class STReranker:
|
|
11
37
|
"""Reranker implementing providers.base.Reranker via a sentence-transformers CrossEncoder."""
|
|
@@ -20,6 +46,9 @@ class STReranker:
|
|
|
20
46
|
"sentence-transformers not installed — install with: uv tool install ragx-cli --with ragx-cli[rerank]"
|
|
21
47
|
) from exc
|
|
22
48
|
self.model = model
|
|
49
|
+
hint = _DownloadHintHandler()
|
|
50
|
+
hub_logger = logging.getLogger("huggingface_hub")
|
|
51
|
+
hub_logger.addHandler(hint)
|
|
23
52
|
try:
|
|
24
53
|
self._encoder = CrossEncoder(model)
|
|
25
54
|
except Exception as exc:
|
|
@@ -30,6 +59,8 @@ class STReranker:
|
|
|
30
59
|
"reranking (rerank.enabled false); see README 'Reranker on restricted "
|
|
31
60
|
"networks (no huggingface.co)'"
|
|
32
61
|
) from exc
|
|
62
|
+
finally:
|
|
63
|
+
hub_logger.removeHandler(hint)
|
|
33
64
|
|
|
34
65
|
def score(self, query: str, texts: Sequence[str]) -> list[float]:
|
|
35
66
|
pairs = [[query, text] for text in texts]
|
|
@@ -200,6 +200,42 @@ def test_make_reranker_model_load_failure_returns_none_and_warns(monkeypatch, ca
|
|
|
200
200
|
assert "HF_ENDPOINT" in err
|
|
201
201
|
|
|
202
202
|
|
|
203
|
+
def test_st_reranker_first_retry_warning_emits_manual_install_hint(monkeypatch, capsys):
|
|
204
|
+
"""The first HF download-retry warning triggers a one-shot README pointer."""
|
|
205
|
+
import logging
|
|
206
|
+
import sys
|
|
207
|
+
import types
|
|
208
|
+
|
|
209
|
+
class _RetryingCrossEncoder:
|
|
210
|
+
def __init__(self, model):
|
|
211
|
+
hub_log = logging.getLogger("huggingface_hub.utils._http")
|
|
212
|
+
for _ in range(2):
|
|
213
|
+
hub_log.warning(
|
|
214
|
+
"'_ssl.c:1015: The handshake operation timed out' thrown while "
|
|
215
|
+
"requesting HEAD https://huggingface.co/x/resolve/main/modules.json"
|
|
216
|
+
)
|
|
217
|
+
hub_log.warning("Retrying in 1s [Retry 1/5].")
|
|
218
|
+
raise OSError("timed out")
|
|
219
|
+
|
|
220
|
+
fake = types.ModuleType("sentence_transformers")
|
|
221
|
+
fake.CrossEncoder = _RetryingCrossEncoder
|
|
222
|
+
monkeypatch.setitem(sys.modules, "sentence_transformers", fake)
|
|
223
|
+
|
|
224
|
+
from ragx.core.errors import RagxError
|
|
225
|
+
from ragx.providers.st_reranker import STReranker, _DownloadHintHandler
|
|
226
|
+
|
|
227
|
+
with pytest.raises(RagxError):
|
|
228
|
+
STReranker("BAAI/bge-reranker-v2-m3")
|
|
229
|
+
|
|
230
|
+
err = capsys.readouterr().err
|
|
231
|
+
assert err.count("install the model manually") == 1
|
|
232
|
+
assert "#reranker-on-restricted-networks" in err
|
|
233
|
+
assert not any(
|
|
234
|
+
isinstance(h, _DownloadHintHandler)
|
|
235
|
+
for h in logging.getLogger("huggingface_hub").handlers
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
|
|
203
239
|
def test_api_key_env_resolved_and_sent(monkeypatch):
|
|
204
240
|
monkeypatch.setenv("RAGX_TEST_KEY", "sk-test-123")
|
|
205
241
|
cfg = _config({"embeddings": {"api_key_env": "RAGX_TEST_KEY"}})
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|