ragx-cli 0.3.3__tar.gz → 0.5.0__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.3 → ragx_cli-0.5.0}/CHANGELOG.md +46 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/CLAUDE.md +16 -4
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/PKG-INFO +80 -12
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/README.md +79 -11
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/pyproject.toml +1 -1
- ragx_cli-0.5.0/research/lm-studio-model-download-api-and-curated-embedding-reranker-catalog-for-ragx-models-command.md +119 -0
- ragx_cli-0.5.0/skills/ragx-cli/SKILL.md +90 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/cli/app.py +19 -2
- ragx_cli-0.5.0/src/ragx/cli/models_cmd.py +230 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/cli/pipeline.py +10 -3
- ragx_cli-0.5.0/src/ragx/core/catalog.py +138 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/config.py +11 -2
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/indexer.py +57 -23
- ragx_cli-0.5.0/src/ragx/core/lmstudio.py +106 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/query.py +1 -1
- ragx_cli-0.5.0/src/ragx/providers/llama_embedder.py +53 -0
- ragx_cli-0.5.0/src/ragx/providers/llama_process.py +108 -0
- ragx_cli-0.5.0/src/ragx/providers/llama_server.py +45 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/providers/registry.py +28 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_cli.py +26 -2
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_integration.py +54 -8
- ragx_cli-0.5.0/tests/test_llama_server.py +135 -0
- ragx_cli-0.5.0/tests/test_models.py +312 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/SKILL.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/api-cheatsheet.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/collection-management/python.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/collection-management/typescript.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/configuration.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/data-model.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/data-operations/python.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/data-operations/typescript.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/embedding.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/hybrid-search/python.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/hybrid-search/typescript.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/multimodal-search/python.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/multimodal-search/typescript.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/quick-start/python.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/quick-start/typescript.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/rag-system/python.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/rag-system/typescript.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/reranker.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/troubleshooting.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/vector-search/python.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.agents/skills/zvec/vector-search/typescript.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.github/workflows/publish.yml +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/.gitignore +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/AGENTS.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/CONTRACTS-PHASE23.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/CONTRACTS.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/LICENSE +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/docs/feature-temporal-weighting.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/ragx-cli-plan.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/research/bge-m3-colbert-multi-vector-late-interaction-for-ragx-rerank-alternative-and-token-level-graph-edges.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/research/bge-m3-dense-embeddings-as-ragx-provider-multilingual-quality-and-threshold-calibration.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/research/bge-m3-dense-q8-vs-nomic-q4-benchmark-2026-07-12-worktree-eval-results.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/research/bge-m3-sparse-lexical-weights-hybrid-retrieval-leg-for-ragx-vs-sqlite-fts5-bm25.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/research/bge-m3-subchunk-edge-ablation-2026-07-13-ties-again-and-beta-zero-shortlist-mechanism.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/research/fine-grained-sub-chunk-edges-with-coarse-chunk-nodes-multi-granularity-graph-rag-literature-validation.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/research/subchunk-edge-ablation-2026-07-12-two-round-experiment-protocol-results-and-verdict.md +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/skills-lock.json +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/__init__.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/cli/__init__.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/cli/detect.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/cli/eval_cmd.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/cli/init_prompt.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/cli/inspect_cmd.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/cli/output.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/__init__.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/chunking.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/communities.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/discovery.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/errors.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/eval.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/expansion.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/fusion.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/graph.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/models.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/scoring.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/store.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/traversal.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/core/vectors.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/providers/__init__.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/providers/base.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/providers/openai_compat.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/src/ragx/providers/st_reranker.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/__init__.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/conftest.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_chunking.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_communities.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_config_rc.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_discovery.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_eval.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_expansion.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_fusion.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_graph.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_inspect.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_providers.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_store.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_traversal.py +0 -0
- {ragx_cli-0.3.3 → ragx_cli-0.5.0}/tests/test_vectors.py +0 -0
|
@@ -4,6 +4,52 @@ 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.5.0] — 2026-07-15
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **`ragx-cli models`**: recommends an embedding + reranker combo (quality tier,
|
|
12
|
+
RAM/macOS detection), downloads models through LM Studio (`lms get --yes`), and writes
|
|
13
|
+
the config to `ragx.toml` (with an `index --full` warning when the embedding model
|
|
14
|
+
changed). Scriptable: `--quality fast|balanced|best|jina-nano`, `--embed-engine`,
|
|
15
|
+
`--rerank-engine`, `--yes`, `--dry-run`, `--json` (schema `ragx.models.v1`).
|
|
16
|
+
Interactive `init` offers the flow as its final step. Embedding catalog:
|
|
17
|
+
EmbeddingGemma-300M / BGE-M3 / Qwen3-Embedding-0.6B / Jina-v5-nano (CC-BY-NC,
|
|
18
|
+
llama-server engine only); reranker: bge-reranker-v2-m3 (multilingual).
|
|
19
|
+
- **`llama-server` rerank engine** (`rerank.provider = "llama-server"`): reranking via
|
|
20
|
+
llama.cpp's `/v1/rerank` on a GGUF (`rerank.gguf`), auto-spawning `llama-server`
|
|
21
|
+
(`rerank.server_bin`, `rerank.base_url`) when nothing is listening and terminating it
|
|
22
|
+
at exit. Reranker GGUFs download through LM Studio (`ragx-cli models --rerank-engine
|
|
23
|
+
llama-server`), so reranking needs **no direct huggingface.co access** and no torch/
|
|
24
|
+
sentence-transformers install. Q8_0 GGUFs validated against the safetensors originals
|
|
25
|
+
(scores within ~0.5 logit, identical ordering).
|
|
26
|
+
- **`llama-server` embedding engine** (`embeddings.provider = "llama-server"`): embeddings
|
|
27
|
+
served by an auto-spawned `llama-server --embedding` on `embeddings.gguf` (same managed
|
|
28
|
+
lifecycle as the rerank engine; default port 9813). `ragx-cli models --embed-engine
|
|
29
|
+
llama-server` wires it up. With both engines on llama-server, LM Studio is purely a
|
|
30
|
+
model downloader — nothing but ragx-managed processes run at query time. Also unblocks
|
|
31
|
+
EuroBERT models (e.g. `jina-embeddings-v5-text-nano-retrieval-GGUF`) that LM Studio
|
|
32
|
+
downloads but cannot serve.
|
|
33
|
+
|
|
34
|
+
## [0.4.0] — 2026-07-15
|
|
35
|
+
|
|
36
|
+
### Changed (BREAKING)
|
|
37
|
+
|
|
38
|
+
- **`ragx-cli index` is now incremental by default** (previously a full rebuild).
|
|
39
|
+
It hash-diffs the corpus and re-processes only new/modified/deleted files. The old
|
|
40
|
+
behavior moved to `ragx-cli index --full`; `--changed` remains as a deprecated,
|
|
41
|
+
hidden alias for the (now default) incremental mode.
|
|
42
|
+
- **Chunking params joined the index manifest**: changing `chunking.size_tokens` or
|
|
43
|
+
`chunking.overlap` now fails loud on an incremental run (previously it silently left
|
|
44
|
+
old files chunked under the old params). Fix is `ragx-cli index --full`.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- **`ragx-cli status` reports corpus drift**: a `drift` object
|
|
49
|
+
(`{"new": N, "changed": N, "deleted": N}`, same in text output) diffing the corpus
|
|
50
|
+
on disk against the stored file hashes, so agents and humans can see when a
|
|
51
|
+
re-index is due without running one.
|
|
52
|
+
|
|
7
53
|
## [0.3.3] — 2026-07-15
|
|
8
54
|
|
|
9
55
|
### Added
|
|
@@ -22,6 +22,9 @@ API contracts for every core module. Deferred feature specs live in `docs/`.
|
|
|
22
22
|
hashing), pathspec (gitignore globs).
|
|
23
23
|
- Providers speak **OpenAI-compatible HTTP**. Local default: LM Studio at
|
|
24
24
|
`http://localhost:1234/v1`. `provider="ollama"` auto-switches to `:11434/v1`.
|
|
25
|
+
`embeddings.provider="llama-server"` instead auto-spawns `llama-server --embedding` on
|
|
26
|
+
`embeddings.gguf` (port 9813; shared lifecycle code in `providers/llama_process.py`) —
|
|
27
|
+
with the llama-server rerank engine, LM Studio is downloader-only at query time.
|
|
25
28
|
Env fallbacks: `OPENAI_BASE_URL` (only while base_url is still the default) and
|
|
26
29
|
`OPENAI_API_KEY` (only when `api_key_env` is unset); explicit config always wins.
|
|
27
30
|
- Machine-level provider settings live in `~/.ragxrc` (TOML; ONLY the embeddings/
|
|
@@ -29,8 +32,11 @@ API contracts for every core module. Deferred feature specs live in `docs/`.
|
|
|
29
32
|
ragx.toml < ~/.ragxrc — the rc OVERRIDES corpus values and logs a stderr warning
|
|
30
33
|
per overridden key. Write via `ragx-cli config set --global <key> <value>`.
|
|
31
34
|
`Config.save` never bakes rc values into the corpus file.
|
|
32
|
-
- Reranker is always local: sentence-transformers CrossEncoder
|
|
33
|
-
|
|
35
|
+
- Reranker is always local, two engines: sentence-transformers CrossEncoder (default,
|
|
36
|
+
`BAAI/bge-reranker-v2-m3`, optional extra `ragx-cli[rerank]`) or `rerank.provider=
|
|
37
|
+
"llama-server"` (llama.cpp `/v1/rerank` on a GGUF, auto-spawned from `rerank.gguf`;
|
|
38
|
+
GGUFs download via LM Studio — validated ≈ safetensors scores). LM Studio itself has
|
|
39
|
+
NO /v1/rerank endpoint — verified; don't try.
|
|
34
40
|
|
|
35
41
|
## Layout (core/CLI split is the one architectural rule — MCP server later rides on it)
|
|
36
42
|
|
|
@@ -57,10 +63,16 @@ src/ragx/
|
|
|
57
63
|
indexer.py # run_index: discover->hash->chunk->embed->HNSW+store->kNN edges
|
|
58
64
|
query.py # run_query: expansion->fan-out->RRF->traversal->rerank->combine; JSON serializers
|
|
59
65
|
eval.py # recall@5/@10 + MRR over file-level ranking, injected query_fn
|
|
66
|
+
catalog.py # curated embedding/reranker catalog (tiers, prefixes) + spec detect
|
|
67
|
+
lmstudio.py # `lms` CLI wrapper: find/download (`lms get --yes`)/`lms ls --json`;
|
|
68
|
+
# LM Studio can't download plain safetensors — rerankers stay on HF
|
|
60
69
|
providers/ # base.py protocols (Embedder/Generator/Reranker); openai_compat.py;
|
|
61
|
-
# st_reranker.py;
|
|
70
|
+
# st_reranker.py; llama_process.py (managed llama-server lifecycle) +
|
|
71
|
+
# llama_server.py (rerank) + llama_embedder.py (embeddings);
|
|
72
|
+
# registry.py factories (env-var + api_key_env resolution)
|
|
62
73
|
cli/ # thin shells only: app.py (init/status/config + registration),
|
|
63
|
-
# pipeline.py (index/query), inspect_cmd.py, eval_cmd.py,
|
|
74
|
+
# pipeline.py (index/query), inspect_cmd.py, eval_cmd.py, models_cmd.py
|
|
75
|
+
# (recommend/download/configure models), output.py
|
|
64
76
|
tests/ # 177 tests; mocked HTTP (respx), FakeEmbedder integration tests, no live network
|
|
65
77
|
```
|
|
66
78
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ragx-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
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
|
|
@@ -49,9 +49,10 @@ that can justify every result via the exact graph path that produced it.
|
|
|
49
49
|
```bash
|
|
50
50
|
uv tool install ragx-cli --with ragx-cli[rerank] # install and use `ragx-cli`
|
|
51
51
|
ragx-cli init # create ragx.toml next to your corpus (interactive on a TTY; --yes for defaults)
|
|
52
|
-
ragx-cli index # chunk -> embed -> HNSW + kNN similarity graph
|
|
52
|
+
ragx-cli index # chunk -> embed -> HNSW + kNN similarity graph (incremental after the first run)
|
|
53
53
|
ragx-cli query "why did we switch build tools?" --json --files-only
|
|
54
|
-
ragx-cli index --
|
|
54
|
+
ragx-cli index --full # full rebuild: re-chunk + re-embed everything
|
|
55
|
+
ragx-cli models # recommend + download an embedding/reranker combo via LM Studio
|
|
55
56
|
```
|
|
56
57
|
|
|
57
58
|
Runs against any OpenAI-compatible embedding endpoint (LM Studio, Ollama, OpenAI). Reranking
|
|
@@ -93,7 +94,7 @@ mixing several concepts gets one sharp edge per concept instead of a diluted ave
|
|
|
93
94
|
between near-duplicate chunks (whole-chunk cosine ≥ `near_dup_sim`) are dropped — those are the
|
|
94
95
|
measured precision-killers. Costs roughly 5–10× more embedding calls at index time; retrieval
|
|
95
96
|
units, traversal, and query flow are unchanged. Switching `edge_source` (or the sub-chunk size)
|
|
96
|
-
requires
|
|
97
|
+
requires `index --full`; incremental runs fail loud on the mismatch. Literature grounding:
|
|
97
98
|
`research/fine-grained-sub-chunk-edges-with-coarse-chunk-nodes-multi-granularity-graph-rag-literature-validation.md`.
|
|
98
99
|
In this mode `k` counts links per *sub-chunk* with no per-chunk cap, so the graph is denser and
|
|
99
100
|
shallower traversal suffices. Measured on the tuned eval corpus (2026-07): at `hops=2` it ties
|
|
@@ -116,8 +117,13 @@ flowchart TD
|
|
|
116
117
|
G --> F
|
|
117
118
|
```
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
`ragx-cli index` is **incremental by default** (0.4.0; `--changed` is a deprecated alias): it
|
|
121
|
+
re-embeds only new/modified files, drops deleted ones, and repairs only the edge lists those
|
|
122
|
+
chunks touch. Content hashes make `touch`-ed but unchanged files free, and include/exclude glob
|
|
123
|
+
changes converge to the same file set a rebuild would produce. `--full` rebuilds from scratch;
|
|
124
|
+
changing `embeddings.model`, `chunking.*`, or `graph.edge_source` requires it — incremental runs
|
|
125
|
+
fail loud on the manifest mismatch. `ragx-cli status` reports **drift** (files new/changed/deleted
|
|
126
|
+
since the last index) so you can see when a re-index is due without running one.
|
|
121
127
|
|
|
122
128
|
### Querying
|
|
123
129
|
|
|
@@ -314,6 +320,53 @@ Full write-ups: `research/bge-m3-dense-q8-vs-nomic-q4-benchmark-2026-07-12-workt
|
|
|
314
320
|
|
|
315
321
|
---
|
|
316
322
|
|
|
323
|
+
## Picking models: `ragx-cli models`
|
|
324
|
+
|
|
325
|
+
`ragx-cli models` recommends an embedding + reranker combo, downloads the embedding model
|
|
326
|
+
**through LM Studio** (`lms get` — one download path, plays well with restricted networks),
|
|
327
|
+
pre-fetches the reranker from Hugging Face, and writes both to `ragx.toml`. Interactive on a
|
|
328
|
+
TTY (quality tier + engine questions, RAM auto-detected); scriptable via flags:
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
ragx-cli models # interactive
|
|
332
|
+
ragx-cli models --quality balanced --yes --json # agents
|
|
333
|
+
ragx-cli models --quality fast --dry-run # recommend only, change nothing
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
The curated catalog (every entry verified working end-to-end):
|
|
337
|
+
|
|
338
|
+
| tier | embedding model | notes |
|
|
339
|
+
|---|---|---|
|
|
340
|
+
| `fast` | EmbeddingGemma 300M | 308M, 100+ languages, 2048-token context |
|
|
341
|
+
| `balanced` | BGE-M3 | ragx's benchmarked production model (~100 languages) |
|
|
342
|
+
| `best` | Qwen3-Embedding-0.6B | 100+ languages, 32K context |
|
|
343
|
+
| `jina-nano` | Jina embeddings v5 nano | 239M, best-in-class sub-500M; **CC-BY-NC (non-commercial)**; llama-server engine only — LM Studio downloads it but can't serve EuroBERT |
|
|
344
|
+
|
|
345
|
+
**Serving engines.** Embeddings run through `--embed-engine`: **`llama-server`** (default when
|
|
346
|
+
llama.cpp is installed — ragx auto-spawns `llama-server --embedding` on the downloaded GGUF and
|
|
347
|
+
terminates it at exit; LM Studio is only the downloader) or **`lm-studio`** (LM Studio serves
|
|
348
|
+
`/v1/embeddings`; zero extra processes, LM Studio must be running). The reranker —
|
|
349
|
+
`BAAI/bge-reranker-v2-m3` (multilingual) — runs through `--rerank-engine`:
|
|
350
|
+
|
|
351
|
+
- **`llama-server`** (default when llama.cpp is installed): the reranker's Q8_0 GGUF is also
|
|
352
|
+
downloaded via LM Studio, and ragx auto-spawns/terminates a `llama-server --rerank` process
|
|
353
|
+
at query time (`rerank.provider="llama-server"`, `rerank.gguf`, `rerank.base_url`,
|
|
354
|
+
`rerank.server_bin`). **No huggingface.co access needed anywhere.** GGUF scores are validated
|
|
355
|
+
within ~0.5 logit of the safetensors originals.
|
|
356
|
+
- **`sentence-transformers`**: the classic CrossEncoder path; model pre-fetched from Hugging
|
|
357
|
+
Face (needs the `ragx-cli[rerank]` extra).
|
|
358
|
+
|
|
359
|
+
With both engines on `llama-server` the whole stack is ragx-managed: LM Studio downloads the
|
|
360
|
+
GGUFs, ragx spawns and reaps the servers, and neither LM Studio nor huggingface.co is needed
|
|
361
|
+
at query time. Under 8 GB RAM the embedding tier drops to `fast`; on macOS
|
|
362
|
+
`lms get --yes` picks MLX variants where LM Studio's catalog offers them. Switching the
|
|
363
|
+
embedding model invalidates the index — the command tells you to run `ragx-cli index --full`.
|
|
364
|
+
`init` offers this flow as its final step; rerun `ragx-cli models` anytime to switch.
|
|
365
|
+
|
|
366
|
+
Why not `jina-embeddings-v5-text-nano`? Excellent model, but its EuroBERT architecture needs
|
|
367
|
+
Jina's llama.cpp fork — stock LM Studio can't load it (and the license is CC-BY-NC). See
|
|
368
|
+
`research/lm-studio-model-download-api-and-curated-embedding-reranker-catalog-for-ragx-models-command.md`.
|
|
369
|
+
|
|
317
370
|
## Agent-first conventions
|
|
318
371
|
|
|
319
372
|
- `--json` emits exactly one JSON document on stdout (versioned schemas: `ragx.query.v1`,
|
|
@@ -322,6 +375,8 @@ Full write-ups: `research/bge-m3-dense-q8-vs-nomic-q4-benchmark-2026-07-12-workt
|
|
|
322
375
|
- Every chunk carries `file`, `line_start/line_end`, `byte_start/byte_end` — agents jump to the
|
|
323
376
|
exact source location and read the full text themselves (JSON chunk text is truncated).
|
|
324
377
|
- `--files-only` aggregates chunk scores per file (sum of top-3) — the mode coding agents use most.
|
|
378
|
+
- `ragx-cli status` includes a `drift` object (`new`/`changed`/`deleted` file counts vs the index) —
|
|
379
|
+
agents check it to decide whether to run `ragx-cli index` before querying.
|
|
325
380
|
- `ragx-cli query -` reads the query from stdin; `ragx-cli inspect chunk|file|neighbors|communities|community`
|
|
326
381
|
debugs the graph.
|
|
327
382
|
|
|
@@ -341,7 +396,8 @@ questions; fall back to grep for exact identifiers.
|
|
|
341
396
|
`file` + `line_start/line_end`; the JSON `text` is truncated, so read the file yourself
|
|
342
397
|
for full context.
|
|
343
398
|
- Fast mode (no LLM call, no cross-encoder): add `--no-expand --no-rerank`.
|
|
344
|
-
- After adding or editing files: `ragx-cli index
|
|
399
|
+
- After adding or editing files: `ragx-cli index` (incremental and cheap — hash-based).
|
|
400
|
+
`ragx-cli status --json` shows `drift` counts if you want to check staleness first.
|
|
345
401
|
- stdout is exactly one JSON document; logs are on stderr.
|
|
346
402
|
Exit codes: 0 = results, 1 = no results (not an error), 2 = error.
|
|
347
403
|
- Why did this result appear? `ragx-cli query "..." --explain`.
|
|
@@ -401,9 +457,19 @@ detects the mismatch and asks you to run a full `ragx-cli index`.
|
|
|
401
457
|
|
|
402
458
|
### Reranker on restricted networks (no huggingface.co)
|
|
403
459
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
460
|
+
With the default `sentence-transformers` engine, the reranker model
|
|
461
|
+
(`BAAI/bge-reranker-v2-m3`, ~2.3 GB) is downloaded from huggingface.co on first use. If your
|
|
462
|
+
network blocks huggingface.co, ragx-cli degrades gracefully — queries run without reranking
|
|
463
|
+
and a warning explains why — and the easiest fix is to skip huggingface.co entirely:
|
|
464
|
+
|
|
465
|
+
**Option 0 — the `llama-server` engine (recommended).** `ragx-cli models --rerank-engine
|
|
466
|
+
llama-server` downloads a validated Q8_0 GGUF of the reranker **through LM Studio** (same
|
|
467
|
+
download path as the embedding model) and reranks via llama.cpp's `llama-server --rerank`,
|
|
468
|
+
which ragx starts and stops automatically. Requires a recent llama.cpp
|
|
469
|
+
(`brew install llama.cpp`); no torch, no sentence-transformers, no huggingface.co. The GGUFs
|
|
470
|
+
score within ~0.5 logit of the safetensors originals with identical ordering.
|
|
471
|
+
|
|
472
|
+
Prefer the sentence-transformers engine? Three more ways:
|
|
407
473
|
|
|
408
474
|
**Option A — copy the model and point `rerank.model` at the directory** (recommended).
|
|
409
475
|
On any machine with access:
|
|
@@ -499,7 +565,7 @@ Checked features are built and validated per [the implementation plan](ragx-cli-
|
|
|
499
565
|
unchecked ones are next up. Release history: [CHANGELOG.md](CHANGELOG.md).
|
|
500
566
|
|
|
501
567
|
- [x] **CLI & storage**: typer CLI, SQLite schema, provider abstraction (Embedder/Generator/Reranker)
|
|
502
|
-
- [x] **Baseline vector RAG**: discovery, chunking, embeddings, HNSW search, incremental
|
|
568
|
+
- [x] **Baseline vector RAG**: discovery, chunking, embeddings, HNSW search, incremental indexing
|
|
503
569
|
- [x] **Similarity graph**: kNN edge construction, heat-propagation traversal, `inspect`, `--explain`
|
|
504
570
|
- [x] **Quality & measurement**: multi-query/HyDE expansion, RRF fusion, cross-encoder rerank, `eval` harness
|
|
505
571
|
- [x] **Communities**: Leiden detection over the edge list (index-time, read-only via status/inspect)
|
|
@@ -507,11 +573,13 @@ unchecked ones are next up. Release history: [CHANGELOG.md](CHANGELOG.md).
|
|
|
507
573
|
- [x] **Committable config**: `ragx.toml` at the corpus root (0.3.0; was `.ragx/config.toml`), index data stays gitignored in `.ragx/`
|
|
508
574
|
- [x] **Offline-friendly rerank**: graceful degradation + pre-seeding docs when huggingface.co is unreachable
|
|
509
575
|
- [x] **Sub-chunk edges** (opt-in `graph.edge_source="subchunk"`): edge weight = max cosine over sentence-aligned sub-chunk pairs, for corpora with long multi-concept chunks
|
|
576
|
+
- [x] **Incremental by default** (0.4.0): `index` hash-diffs, `--full` rebuilds, `status` reports corpus drift, chunking params are manifest-guarded
|
|
577
|
+
- [x] **`ragx-cli models`**: curated embedding/reranker recommendation (quality tier + RAM detection), downloads via LM Studio's `lms get`, serving via llama-server or LM Studio
|
|
510
578
|
- [ ] **Community labels**: name the Leiden communities so they're browsable without reading member chunks
|
|
511
579
|
- [ ] **query --global** for corpus-level questions (answer from community summaries, not individual chunks)
|
|
512
580
|
- [ ] **MCP server**: a second thin shell over `ragx.core` (the core/CLI split it needs is already enforced)
|
|
513
581
|
- [ ] **[Temporal weighting](docs/feature-temporal-weighting.md)**: opt-in `--since`/`--until`/`--temporal recent|oldest`, date cascade filename/frontmatter → git → mtime
|
|
514
582
|
- [x] **Release**: publish to PyPI as `ragx-cli` (plain `ragx` is name-blocked, too similar to an existing project) so `uvx ragx-cli` works out of the box
|
|
515
583
|
|
|
516
|
-
Development: `uv sync --group dev && uv run pytest`.
|
|
584
|
+
Development: `uv sync --group dev && uv run pytest`. 183 tests; module contracts live in
|
|
517
585
|
`CONTRACTS.md` / `CONTRACTS-PHASE23.md`.
|
|
@@ -21,9 +21,10 @@ that can justify every result via the exact graph path that produced it.
|
|
|
21
21
|
```bash
|
|
22
22
|
uv tool install ragx-cli --with ragx-cli[rerank] # install and use `ragx-cli`
|
|
23
23
|
ragx-cli init # create ragx.toml next to your corpus (interactive on a TTY; --yes for defaults)
|
|
24
|
-
ragx-cli index # chunk -> embed -> HNSW + kNN similarity graph
|
|
24
|
+
ragx-cli index # chunk -> embed -> HNSW + kNN similarity graph (incremental after the first run)
|
|
25
25
|
ragx-cli query "why did we switch build tools?" --json --files-only
|
|
26
|
-
ragx-cli index --
|
|
26
|
+
ragx-cli index --full # full rebuild: re-chunk + re-embed everything
|
|
27
|
+
ragx-cli models # recommend + download an embedding/reranker combo via LM Studio
|
|
27
28
|
```
|
|
28
29
|
|
|
29
30
|
Runs against any OpenAI-compatible embedding endpoint (LM Studio, Ollama, OpenAI). Reranking
|
|
@@ -65,7 +66,7 @@ mixing several concepts gets one sharp edge per concept instead of a diluted ave
|
|
|
65
66
|
between near-duplicate chunks (whole-chunk cosine ≥ `near_dup_sim`) are dropped — those are the
|
|
66
67
|
measured precision-killers. Costs roughly 5–10× more embedding calls at index time; retrieval
|
|
67
68
|
units, traversal, and query flow are unchanged. Switching `edge_source` (or the sub-chunk size)
|
|
68
|
-
requires
|
|
69
|
+
requires `index --full`; incremental runs fail loud on the mismatch. Literature grounding:
|
|
69
70
|
`research/fine-grained-sub-chunk-edges-with-coarse-chunk-nodes-multi-granularity-graph-rag-literature-validation.md`.
|
|
70
71
|
In this mode `k` counts links per *sub-chunk* with no per-chunk cap, so the graph is denser and
|
|
71
72
|
shallower traversal suffices. Measured on the tuned eval corpus (2026-07): at `hops=2` it ties
|
|
@@ -88,8 +89,13 @@ flowchart TD
|
|
|
88
89
|
G --> F
|
|
89
90
|
```
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
`ragx-cli index` is **incremental by default** (0.4.0; `--changed` is a deprecated alias): it
|
|
93
|
+
re-embeds only new/modified files, drops deleted ones, and repairs only the edge lists those
|
|
94
|
+
chunks touch. Content hashes make `touch`-ed but unchanged files free, and include/exclude glob
|
|
95
|
+
changes converge to the same file set a rebuild would produce. `--full` rebuilds from scratch;
|
|
96
|
+
changing `embeddings.model`, `chunking.*`, or `graph.edge_source` requires it — incremental runs
|
|
97
|
+
fail loud on the manifest mismatch. `ragx-cli status` reports **drift** (files new/changed/deleted
|
|
98
|
+
since the last index) so you can see when a re-index is due without running one.
|
|
93
99
|
|
|
94
100
|
### Querying
|
|
95
101
|
|
|
@@ -286,6 +292,53 @@ Full write-ups: `research/bge-m3-dense-q8-vs-nomic-q4-benchmark-2026-07-12-workt
|
|
|
286
292
|
|
|
287
293
|
---
|
|
288
294
|
|
|
295
|
+
## Picking models: `ragx-cli models`
|
|
296
|
+
|
|
297
|
+
`ragx-cli models` recommends an embedding + reranker combo, downloads the embedding model
|
|
298
|
+
**through LM Studio** (`lms get` — one download path, plays well with restricted networks),
|
|
299
|
+
pre-fetches the reranker from Hugging Face, and writes both to `ragx.toml`. Interactive on a
|
|
300
|
+
TTY (quality tier + engine questions, RAM auto-detected); scriptable via flags:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
ragx-cli models # interactive
|
|
304
|
+
ragx-cli models --quality balanced --yes --json # agents
|
|
305
|
+
ragx-cli models --quality fast --dry-run # recommend only, change nothing
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
The curated catalog (every entry verified working end-to-end):
|
|
309
|
+
|
|
310
|
+
| tier | embedding model | notes |
|
|
311
|
+
|---|---|---|
|
|
312
|
+
| `fast` | EmbeddingGemma 300M | 308M, 100+ languages, 2048-token context |
|
|
313
|
+
| `balanced` | BGE-M3 | ragx's benchmarked production model (~100 languages) |
|
|
314
|
+
| `best` | Qwen3-Embedding-0.6B | 100+ languages, 32K context |
|
|
315
|
+
| `jina-nano` | Jina embeddings v5 nano | 239M, best-in-class sub-500M; **CC-BY-NC (non-commercial)**; llama-server engine only — LM Studio downloads it but can't serve EuroBERT |
|
|
316
|
+
|
|
317
|
+
**Serving engines.** Embeddings run through `--embed-engine`: **`llama-server`** (default when
|
|
318
|
+
llama.cpp is installed — ragx auto-spawns `llama-server --embedding` on the downloaded GGUF and
|
|
319
|
+
terminates it at exit; LM Studio is only the downloader) or **`lm-studio`** (LM Studio serves
|
|
320
|
+
`/v1/embeddings`; zero extra processes, LM Studio must be running). The reranker —
|
|
321
|
+
`BAAI/bge-reranker-v2-m3` (multilingual) — runs through `--rerank-engine`:
|
|
322
|
+
|
|
323
|
+
- **`llama-server`** (default when llama.cpp is installed): the reranker's Q8_0 GGUF is also
|
|
324
|
+
downloaded via LM Studio, and ragx auto-spawns/terminates a `llama-server --rerank` process
|
|
325
|
+
at query time (`rerank.provider="llama-server"`, `rerank.gguf`, `rerank.base_url`,
|
|
326
|
+
`rerank.server_bin`). **No huggingface.co access needed anywhere.** GGUF scores are validated
|
|
327
|
+
within ~0.5 logit of the safetensors originals.
|
|
328
|
+
- **`sentence-transformers`**: the classic CrossEncoder path; model pre-fetched from Hugging
|
|
329
|
+
Face (needs the `ragx-cli[rerank]` extra).
|
|
330
|
+
|
|
331
|
+
With both engines on `llama-server` the whole stack is ragx-managed: LM Studio downloads the
|
|
332
|
+
GGUFs, ragx spawns and reaps the servers, and neither LM Studio nor huggingface.co is needed
|
|
333
|
+
at query time. Under 8 GB RAM the embedding tier drops to `fast`; on macOS
|
|
334
|
+
`lms get --yes` picks MLX variants where LM Studio's catalog offers them. Switching the
|
|
335
|
+
embedding model invalidates the index — the command tells you to run `ragx-cli index --full`.
|
|
336
|
+
`init` offers this flow as its final step; rerun `ragx-cli models` anytime to switch.
|
|
337
|
+
|
|
338
|
+
Why not `jina-embeddings-v5-text-nano`? Excellent model, but its EuroBERT architecture needs
|
|
339
|
+
Jina's llama.cpp fork — stock LM Studio can't load it (and the license is CC-BY-NC). See
|
|
340
|
+
`research/lm-studio-model-download-api-and-curated-embedding-reranker-catalog-for-ragx-models-command.md`.
|
|
341
|
+
|
|
289
342
|
## Agent-first conventions
|
|
290
343
|
|
|
291
344
|
- `--json` emits exactly one JSON document on stdout (versioned schemas: `ragx.query.v1`,
|
|
@@ -294,6 +347,8 @@ Full write-ups: `research/bge-m3-dense-q8-vs-nomic-q4-benchmark-2026-07-12-workt
|
|
|
294
347
|
- Every chunk carries `file`, `line_start/line_end`, `byte_start/byte_end` — agents jump to the
|
|
295
348
|
exact source location and read the full text themselves (JSON chunk text is truncated).
|
|
296
349
|
- `--files-only` aggregates chunk scores per file (sum of top-3) — the mode coding agents use most.
|
|
350
|
+
- `ragx-cli status` includes a `drift` object (`new`/`changed`/`deleted` file counts vs the index) —
|
|
351
|
+
agents check it to decide whether to run `ragx-cli index` before querying.
|
|
297
352
|
- `ragx-cli query -` reads the query from stdin; `ragx-cli inspect chunk|file|neighbors|communities|community`
|
|
298
353
|
debugs the graph.
|
|
299
354
|
|
|
@@ -313,7 +368,8 @@ questions; fall back to grep for exact identifiers.
|
|
|
313
368
|
`file` + `line_start/line_end`; the JSON `text` is truncated, so read the file yourself
|
|
314
369
|
for full context.
|
|
315
370
|
- Fast mode (no LLM call, no cross-encoder): add `--no-expand --no-rerank`.
|
|
316
|
-
- After adding or editing files: `ragx-cli index
|
|
371
|
+
- After adding or editing files: `ragx-cli index` (incremental and cheap — hash-based).
|
|
372
|
+
`ragx-cli status --json` shows `drift` counts if you want to check staleness first.
|
|
317
373
|
- stdout is exactly one JSON document; logs are on stderr.
|
|
318
374
|
Exit codes: 0 = results, 1 = no results (not an error), 2 = error.
|
|
319
375
|
- Why did this result appear? `ragx-cli query "..." --explain`.
|
|
@@ -373,9 +429,19 @@ detects the mismatch and asks you to run a full `ragx-cli index`.
|
|
|
373
429
|
|
|
374
430
|
### Reranker on restricted networks (no huggingface.co)
|
|
375
431
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
432
|
+
With the default `sentence-transformers` engine, the reranker model
|
|
433
|
+
(`BAAI/bge-reranker-v2-m3`, ~2.3 GB) is downloaded from huggingface.co on first use. If your
|
|
434
|
+
network blocks huggingface.co, ragx-cli degrades gracefully — queries run without reranking
|
|
435
|
+
and a warning explains why — and the easiest fix is to skip huggingface.co entirely:
|
|
436
|
+
|
|
437
|
+
**Option 0 — the `llama-server` engine (recommended).** `ragx-cli models --rerank-engine
|
|
438
|
+
llama-server` downloads a validated Q8_0 GGUF of the reranker **through LM Studio** (same
|
|
439
|
+
download path as the embedding model) and reranks via llama.cpp's `llama-server --rerank`,
|
|
440
|
+
which ragx starts and stops automatically. Requires a recent llama.cpp
|
|
441
|
+
(`brew install llama.cpp`); no torch, no sentence-transformers, no huggingface.co. The GGUFs
|
|
442
|
+
score within ~0.5 logit of the safetensors originals with identical ordering.
|
|
443
|
+
|
|
444
|
+
Prefer the sentence-transformers engine? Three more ways:
|
|
379
445
|
|
|
380
446
|
**Option A — copy the model and point `rerank.model` at the directory** (recommended).
|
|
381
447
|
On any machine with access:
|
|
@@ -471,7 +537,7 @@ Checked features are built and validated per [the implementation plan](ragx-cli-
|
|
|
471
537
|
unchecked ones are next up. Release history: [CHANGELOG.md](CHANGELOG.md).
|
|
472
538
|
|
|
473
539
|
- [x] **CLI & storage**: typer CLI, SQLite schema, provider abstraction (Embedder/Generator/Reranker)
|
|
474
|
-
- [x] **Baseline vector RAG**: discovery, chunking, embeddings, HNSW search, incremental
|
|
540
|
+
- [x] **Baseline vector RAG**: discovery, chunking, embeddings, HNSW search, incremental indexing
|
|
475
541
|
- [x] **Similarity graph**: kNN edge construction, heat-propagation traversal, `inspect`, `--explain`
|
|
476
542
|
- [x] **Quality & measurement**: multi-query/HyDE expansion, RRF fusion, cross-encoder rerank, `eval` harness
|
|
477
543
|
- [x] **Communities**: Leiden detection over the edge list (index-time, read-only via status/inspect)
|
|
@@ -479,11 +545,13 @@ unchecked ones are next up. Release history: [CHANGELOG.md](CHANGELOG.md).
|
|
|
479
545
|
- [x] **Committable config**: `ragx.toml` at the corpus root (0.3.0; was `.ragx/config.toml`), index data stays gitignored in `.ragx/`
|
|
480
546
|
- [x] **Offline-friendly rerank**: graceful degradation + pre-seeding docs when huggingface.co is unreachable
|
|
481
547
|
- [x] **Sub-chunk edges** (opt-in `graph.edge_source="subchunk"`): edge weight = max cosine over sentence-aligned sub-chunk pairs, for corpora with long multi-concept chunks
|
|
548
|
+
- [x] **Incremental by default** (0.4.0): `index` hash-diffs, `--full` rebuilds, `status` reports corpus drift, chunking params are manifest-guarded
|
|
549
|
+
- [x] **`ragx-cli models`**: curated embedding/reranker recommendation (quality tier + RAM detection), downloads via LM Studio's `lms get`, serving via llama-server or LM Studio
|
|
482
550
|
- [ ] **Community labels**: name the Leiden communities so they're browsable without reading member chunks
|
|
483
551
|
- [ ] **query --global** for corpus-level questions (answer from community summaries, not individual chunks)
|
|
484
552
|
- [ ] **MCP server**: a second thin shell over `ragx.core` (the core/CLI split it needs is already enforced)
|
|
485
553
|
- [ ] **[Temporal weighting](docs/feature-temporal-weighting.md)**: opt-in `--since`/`--until`/`--temporal recent|oldest`, date cascade filename/frontmatter → git → mtime
|
|
486
554
|
- [x] **Release**: publish to PyPI as `ragx-cli` (plain `ragx` is name-blocked, too similar to an existing project) so `uvx ragx-cli` works out of the box
|
|
487
555
|
|
|
488
|
-
Development: `uv sync --group dev && uv run pytest`.
|
|
556
|
+
Development: `uv sync --group dev && uv run pytest`. 183 tests; module contracts live in
|
|
489
557
|
`CONTRACTS.md` / `CONTRACTS-PHASE23.md`.
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# LM Studio model downloads + curated embedding/reranker catalog for `ragx-cli models`
|
|
2
|
+
|
|
3
|
+
Date: 2026-07-15. Sources: lmstudio.ai official docs, lmstudio-ai/lms + lmstudio-python source,
|
|
4
|
+
Hugging Face model cards, live tests on LM Studio 0.4.12 (this machine). Full agent reports
|
|
5
|
+
summarized here; doc URLs at the bottom.
|
|
6
|
+
|
|
7
|
+
## 1. How to trigger LM Studio downloads programmatically
|
|
8
|
+
|
|
9
|
+
Three mechanisms exist; capabilities verified live on 0.4.12:
|
|
10
|
+
|
|
11
|
+
| Mechanism | Unattended | Needs server up | Notes |
|
|
12
|
+
|---|---|---|---|
|
|
13
|
+
| `lms get <ref> --yes` | yes (exit 0/1, ANSI noise on stdout) | **no** | `<ref>` = catalog id (`google/embedding-gemma-300m`), search term, or full HF URL; `@quant` suffix; `--gguf`/`--mlx` filters. `--yes` auto-picks the hardware-preferred variant. |
|
|
14
|
+
| REST `POST /api/v1/models/download` + poll `GET /api/v1/models/download/status/:job_id` | yes (clean JSON) | yes, ≥0.4.0 | structured errors (`model_not_found`); optional bearer auth off by default. |
|
|
15
|
+
| Python SDK `lmstudio` (`client.repository.search_models → get_download_options → download`) | yes (blocking + progress callback) | yes | extra dependency; nicest API. |
|
|
16
|
+
|
|
17
|
+
- `lms` ships with the app (linked at `~/.lmstudio/bin/lms` after first app run); detect via
|
|
18
|
+
`shutil.which("lms")` + that fallback path. `lms version` prints no semver (use the app plist
|
|
19
|
+
on macOS if ever needed).
|
|
20
|
+
- Verify success + resolve the served model key via `lms ls --json`: entries carry `modelKey`,
|
|
21
|
+
`type` (`"embedding"`/`"llm"`), `format` (`gguf`/`mlx`), `path` (relative to models root),
|
|
22
|
+
`sizeBytes`, `architecture`.
|
|
23
|
+
- Downloads land in `<lmstudio-home>/models/{publisher}/{repo}/…`; home found via
|
|
24
|
+
`~/.lmstudio-home-pointer` (internal, not contractual).
|
|
25
|
+
- REST has **no** catalog-search endpoint; SDK does.
|
|
26
|
+
|
|
27
|
+
**Hard limitation (verified live, twice):** LM Studio only downloads GGUF or MLX-converted
|
|
28
|
+
artifacts. Plain transformers safetensors repos are rejected at resolution time —
|
|
29
|
+
`lms get https://huggingface.co/Alibaba-NLP/gte-reranker-modernbert-base --yes` → exit 1,
|
|
30
|
+
"No download options available". A GGUF conversion of that reranker exists
|
|
31
|
+
(`jolleyboy/gte-reranker-modernbert-base-GGUF`) and downloads fine, but sentence-transformers
|
|
32
|
+
cannot load GGUF, and LM Studio has no /v1/rerank endpoint to serve it. **Conclusion: the
|
|
33
|
+
reranker cannot ride the LM Studio download path in any usable form; it stays on the
|
|
34
|
+
HF/sentence-transformers path** (huggingface_hub `snapshot_download` for pre-fetching).
|
|
35
|
+
|
|
36
|
+
## 2. Requested models — verdicts
|
|
37
|
+
|
|
38
|
+
### jina-embeddings-v5-text-nano (`jinaai/jina-embeddings-v5-text-nano`)
|
|
39
|
+
Real (released 2026-02-18): 239M EuroBERT-based, 768 dims (Matryoshka 32–768), 8192 ctx,
|
|
40
|
+
71.0 MTEB-en — best-in-class sub-500M. BUT:
|
|
41
|
+
- **EuroBERT is not supported by stock llama.cpp** — Jina's cards say to use *their fork*;
|
|
42
|
+
LM Studio ships stock llama.cpp, so the GGUF repos (`…-nano-retrieval[-GGUF]`) won't load.
|
|
43
|
+
- The MLX ports (`…-nano-mlx`) are custom-code (own `model.py`), not LM Studio-loadable.
|
|
44
|
+
- License **CC-BY-NC-4.0** (non-commercial) — bad default for a recommendation catalog.
|
|
45
|
+
→ Excluded from the catalog until upstream llama.cpp support lands. Revisit: watch
|
|
46
|
+
ggml-org/llama.cpp for EuroBERT and ollama/ollama#14641.
|
|
47
|
+
|
|
48
|
+
### gte-reranker-modernbert-base (`Alibaba-NLP/gte-reranker-modernbert-base`)
|
|
49
|
+
149M ModernBERT cross-encoder, 8192 ctx, Apache-2.0, loads in `CrossEncoder(...)` natively
|
|
50
|
+
(transformers ≥4.48, no trust_remote_code). BEIR 56.73; third-party Feb-2026 benchmark: tied
|
|
51
|
+
best Hit@1 at 8× smaller than a 1.2B competitor, ahead of bge-reranker-v2-m3 — on **English**.
|
|
52
|
+
It is English-only; ragx's eval corpus is EN+NL where bge-reranker-v2-m3's multilingual
|
|
53
|
+
training is the reason the Dutch recall win exists. → Catalog **English tier** reranker;
|
|
54
|
+
bge-reranker-v2-m3 stays the multilingual tier/default.
|
|
55
|
+
|
|
56
|
+
## 3. Curated catalog (all embedding entries verified LM Studio-loadable)
|
|
57
|
+
|
|
58
|
+
| Tier | Model | Why | Prefixes |
|
|
59
|
+
|---|---|---|---|
|
|
60
|
+
| fast | `lmstudio-community/embeddinggemma-300m-qat-GGUF` (curated catalog id `google/embedding-gemma-300m`) | 308M, 100+ langs, in LM Studio's own catalog; 2048 ctx / 768 dims cap quality | query `"task: search result \| query: "`, doc `"title: none \| text: "` |
|
|
61
|
+
| balanced | BGE-M3 GGUF (`gaianet/bge-m3-GGUF`) | current ragx production model; ~100 langs, 1024 dims, 8192 ctx, MIT; benchmarked best on the ragx eval corpus | none |
|
|
62
|
+
| best | `Qwen/Qwen3-Embedding-0.6B-GGUF` | Apache-2.0, 100+ langs, 32K ctx, MRL 1024 dims; top multilingual MTEB family; runs on upstream llama.cpp (early 0.3.16/0.3.17 LM Studio bugs since fixed) | query instruct prefix, doc none |
|
|
63
|
+
| reranker (multilingual, default) | `BAAI/bge-reranker-v2-m3` | current default; only clean multilingual CrossEncoder without trust_remote_code | – |
|
|
64
|
+
| reranker (English) | `Alibaba-NLP/gte-reranker-modernbert-base` | 149M, faster, beats bge-v2-m3 on EN benchmarks | – |
|
|
65
|
+
|
|
66
|
+
Rejected alternatives: `gte-multilingual-reranker-base` (306M, good numbers, but needs
|
|
67
|
+
trust_remote_code — security/UX friction), `jina-reranker-v2-base-multilingual` (NC license,
|
|
68
|
+
trust_remote_code, 1024-tok window), `Qwen3-Reranker-0.6B` (causal-LM yes/no scoring, doesn't
|
|
69
|
+
fit the CrossEncoder wrapper).
|
|
70
|
+
|
|
71
|
+
All three embedding tiers are multilingual, so the "multilingual?" question only steers the
|
|
72
|
+
reranker (EN → gte, otherwise bge-v2-m3). Spec detection: total RAM (<8 GB → force fast tier);
|
|
73
|
+
macOS → let `lms get --yes` hardware-preselect MLX where LM Studio's catalog offers it
|
|
74
|
+
(pinned GGUF URLs stay GGUF — they run on Metal fine; that's how bge-m3 Q8 runs today).
|
|
75
|
+
|
|
76
|
+
## 4. Design consequences for `ragx-cli models`
|
|
77
|
+
|
|
78
|
+
- Prefer `lms` CLI subprocess over REST/SDK: works with the server down, zero new deps.
|
|
79
|
+
Absent `lms` → graceful message pointing at lmstudio.ai.
|
|
80
|
+
- After `lms get` exit 0: re-run `lms ls --json`, match the new entry by repo fragment, use its
|
|
81
|
+
`modelKey` as `embeddings.model`, and write the tier's doc/query prefixes to config.
|
|
82
|
+
- Reranker pre-fetch: `huggingface_hub.snapshot_download` (ships with the `rerank` extra);
|
|
83
|
+
degrade to a printed hint when the extra isn't installed.
|
|
84
|
+
- Changing `embeddings.model` invalidates the index (manifest guard) → command must end with a
|
|
85
|
+
loud `ragx-cli index --full` pointer, never auto-reindex.
|
|
86
|
+
|
|
87
|
+
## Decision outcomes (2026-07-15, reviewed by Albert — folded from the session's DECISIONS.md)
|
|
88
|
+
|
|
89
|
+
1. **jina-embeddings-v5-text-nano**: first excluded (stock LM Studio couldn't load EuroBERT),
|
|
90
|
+
then EuroBERT landed in upstream llama.cpp and the retrieval GGUF proved out end-to-end via
|
|
91
|
+
`llama-server --embedding` → **included as the 4th catalog option** (`--quality jina-nano`),
|
|
92
|
+
llama-server engine only, CC-BY-NC warning attached. LM Studio still downloads-but-misclassifies
|
|
93
|
+
it (`type: "llm"` → its /v1/embeddings refuses; candidate LM Studio bug report).
|
|
94
|
+
2. **Reranker delivery**: HF-only at first (LM Studio rejects safetensors; ST can't read GGUF);
|
|
95
|
+
superseded the same day by `rerank.provider="llama-server"` — GGUF via LM Studio, served by
|
|
96
|
+
an auto-spawned `llama-server --rerank`. Q8_0 GGUFs validated ≈ safetensors (within ~0.5
|
|
97
|
+
logit, identical ordering — the all-negative bge logits on toy Dutch pairs match safetensors
|
|
98
|
+
exactly; model behavior, not conversion loss). Verified on brew llama.cpp 9960.
|
|
99
|
+
3. **gte-reranker-modernbert-base (English-only) dropped entirely** per Albert — one multilingual
|
|
100
|
+
reranker (bge-reranker-v2-m3) keeps the measured Dutch-recall win; the multilingual question
|
|
101
|
+
left the CLI with it.
|
|
102
|
+
4. **Downloads**: `lms get --yes` subprocess (works with the server down, zero deps) over REST/SDK.
|
|
103
|
+
5. **MLX**: no hard pinning; `lms get --yes` hardware-preselects; explicit `gguf_ref`s exist per
|
|
104
|
+
entry because the llama-server engine can't load MLX.
|
|
105
|
+
6. **Embedding tiers**: embeddinggemma-300m / bge-m3 / qwen3-embedding-0.6b confirmed by Albert.
|
|
106
|
+
7. **Single-engine mode** (Albert's direction): `embeddings.provider="llama-server"` mirrors the
|
|
107
|
+
rerank engine (shared `providers/llama_process.py`, ports 9813/9814, atexit reaping); both
|
|
108
|
+
engine prompts default to llama-server when the binary exists — LM Studio becomes
|
|
109
|
+
downloader-only at query time. Trade-off: ~1–2 s cold-spawn per engine per process lifetime.
|
|
110
|
+
8. **No auto-reindex on model switch** — loud `ragx-cli index --full` pointer instead; rebuild
|
|
111
|
+
spend stays explicit.
|
|
112
|
+
|
|
113
|
+
## Doc URLs
|
|
114
|
+
|
|
115
|
+
lmstudio.ai/docs/cli · /docs/cli/get · /docs/developer/rest · /docs/developer/rest/download ·
|
|
116
|
+
/docs/developer/rest/download-status · /docs/python · github.com/lmstudio-ai/lms ·
|
|
117
|
+
github.com/lmstudio-ai/lmstudio-python · huggingface.co/jinaai/jina-embeddings-v5-text-nano ·
|
|
118
|
+
huggingface.co/Alibaba-NLP/gte-reranker-modernbert-base · huggingface.co/Qwen/Qwen3-Embedding-0.6B-GGUF ·
|
|
119
|
+
lmstudio.ai/models/google/embedding-gemma-300m · huggingface.co/BAAI/bge-reranker-v2-m3
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ragx-cli
|
|
3
|
+
description: |
|
|
4
|
+
Query a ragx-cli semantic index instead of grepping. Use when the user asks a conceptual or
|
|
5
|
+
natural-language question about a corpus ("where is X discussed/decided?", "find notes about Y"),
|
|
6
|
+
when you are about to grep/rg for a concept (not an exact identifier) in a directory that contains
|
|
7
|
+
a `.ragx/` folder or `ragx.toml`, or when the user says `/ragx`, "search my notes", or "semantic
|
|
8
|
+
search". Covers running queries, interpreting the JSON output, and keeping the index fresh.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# ragx-cli — semantic search over an indexed corpus
|
|
12
|
+
|
|
13
|
+
Indexes files into a chunk-level embedding similarity graph; answers queries via vector search +
|
|
14
|
+
graph traversal + cross-encoder rerank. Agent-first: one JSON doc on stdout, logs on stderr,
|
|
15
|
+
deterministic exit codes, byte-exact source locations.
|
|
16
|
+
|
|
17
|
+
## When
|
|
18
|
+
|
|
19
|
+
A corpus is ragx-indexed if its root has `ragx.toml` and `.ragx/`.
|
|
20
|
+
|
|
21
|
+
- Use ragx-cli for conceptual, natural-language questions ("where do we discuss auth tradeoffs?",
|
|
22
|
+
cross-language queries). Full questions beat keywords.
|
|
23
|
+
- Use grep/rg for exact identifiers and literal strings. ragx does not replace it.
|
|
24
|
+
- Not on PATH: `uvx ragx-cli …` works (PyPI name is `ragx-cli`). Run from anywhere inside the
|
|
25
|
+
corpus — root is found upward.
|
|
26
|
+
|
|
27
|
+
## Commands
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
ragx-cli status --json # root, model, counts, and drift (new/changed/deleted vs index)
|
|
31
|
+
ragx-cli query "question" --json --files-only # which files are relevant — most-used mode
|
|
32
|
+
ragx-cli query "..." --json --top 8 # ranked chunks with exact locations
|
|
33
|
+
ragx-cli query "..." --json --no-expand --no-rerank # fast: skip LLM call + cross-encoder
|
|
34
|
+
echo "..." | ragx-cli query - --json # long/multiline query from stdin
|
|
35
|
+
ragx-cli index # incremental reindex (hash-based, cheap) — the default
|
|
36
|
+
ragx-cli index --full # full rebuild: re-chunks + re-embeds everything
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Other query flags: `--no-graph`, `--hops N`, `--explain`.
|
|
40
|
+
|
|
41
|
+
## Output
|
|
42
|
+
|
|
43
|
+
- stdout is exactly one JSON doc (`ragx.query.v1` / `ragx.files.v1` / `ragx.status.v1`); logs go
|
|
44
|
+
to stderr. Never parse stderr.
|
|
45
|
+
- Exit codes: `0` results, `1` success-but-empty (report "nothing found", don't retry as failure),
|
|
46
|
+
`2` error.
|
|
47
|
+
- Chunk results carry `file`, `line_start/end`, `byte_start/end`, `score`, `breakdown`. JSON
|
|
48
|
+
`text` is truncated — read the file at the line range for full context.
|
|
49
|
+
- Typical flow: `--files-only` to pick files → `--top 8` for locations → read files at ranges.
|
|
50
|
+
|
|
51
|
+
## Freshness
|
|
52
|
+
|
|
53
|
+
- `status` includes `drift` counts; nonzero means the index is stale → run `ragx-cli index`
|
|
54
|
+
(incremental, safe, converges even after include/exclude glob changes).
|
|
55
|
+
- Changing `embeddings.model`, `chunking.*`, or `graph.edge_source` invalidates the index:
|
|
56
|
+
commands fail loud on the manifest mismatch, and the fix is `ragx-cli index --full` —
|
|
57
|
+
re-embeds everything, so confirm before running on a large corpus.
|
|
58
|
+
- `ragx-cli models` picks + downloads an embedding/reranker combo. All files download via
|
|
59
|
+
LM Studio; serving is per engine — `--embed-engine llama-server|lm-studio` and
|
|
60
|
+
`--rerank-engine llama-server|sentence-transformers`. With both on `llama-server`
|
|
61
|
+
(the default when llama.cpp is installed), ragx auto-spawns/reaps the servers and
|
|
62
|
+
needs neither LM Studio nor huggingface.co at query time. Other flags: `--quality
|
|
63
|
+
fast|balanced|best|jina-nano`, `--yes`, `--dry-run`, `--json`.
|
|
64
|
+
|
|
65
|
+
## Why did/didn't a result appear?
|
|
66
|
+
|
|
67
|
+
- `ragx-cli query "..." --explain` — per-result trace: seed, graph edge, hop.
|
|
68
|
+
- `ragx-cli inspect neighbors <chunk_id>` / `inspect chunk <id>` / `inspect file <path>` /
|
|
69
|
+
`inspect communities` / `inspect community <id>`.
|
|
70
|
+
|
|
71
|
+
## Gotchas
|
|
72
|
+
|
|
73
|
+
- The embedding provider must be reachable (default: LM Studio at `localhost:1234`; Ollama and
|
|
74
|
+
any OpenAI-compatible endpoint via config). On connection error, report it and suggest starting
|
|
75
|
+
the provider — never silently fall back to grep.
|
|
76
|
+
- Query expansion degrades gracefully (LLM down → no-op); embeddings do not.
|
|
77
|
+
- `--changed` is a deprecated alias — incremental is the default now.
|
|
78
|
+
- The corpus may be someone's personal notes repo: never `git add`/commit there. Querying and
|
|
79
|
+
`ragx-cli index` are safe.
|
|
80
|
+
|
|
81
|
+
## New corpus (only when asked)
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
ragx-cli init
|
|
85
|
+
ragx-cli config set embeddings.model <model-id> # match what the provider serves
|
|
86
|
+
ragx-cli index
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Provider recipes are in the ragx-cli README. Check `ragx-cli status` and
|
|
90
|
+
`curl -s http://localhost:1234/v1/models` before guessing model ids.
|