ragx-cli 0.1.0__tar.gz → 0.1.1__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.1.0 → ragx_cli-0.1.1}/CLAUDE.md +2 -2
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/CONTRACTS-PHASE23.md +5 -5
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/CONTRACTS.md +5 -5
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/PKG-INFO +3 -3
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/README.md +2 -2
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/docs/feature-temporal-weighting.md +2 -2
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/pyproject.toml +1 -1
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/ragx-cli-plan.md +12 -12
- ragx_cli-0.1.1/src/ragx/__init__.py +1 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/cli/app.py +1 -1
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/cli/eval_cmd.py +1 -1
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/cli/inspect_cmd.py +1 -1
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/config.py +2 -2
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/indexer.py +1 -1
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/query.py +1 -1
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/providers/registry.py +1 -1
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/providers/st_reranker.py +1 -1
- ragx_cli-0.1.0/src/ragx/__init__.py +0 -1
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/.github/workflows/publish.yml +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/.gitignore +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/AGENTS.md +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/LICENSE +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/cli/__init__.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/cli/output.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/cli/pipeline.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/__init__.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/chunking.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/discovery.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/errors.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/eval.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/expansion.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/fusion.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/graph.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/models.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/scoring.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/store.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/traversal.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/core/vectors.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/providers/__init__.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/providers/base.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/src/ragx/providers/openai_compat.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/__init__.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_chunking.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_cli.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_discovery.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_eval.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_expansion.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_fusion.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_graph.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_inspect.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_integration.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_providers.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_store.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_traversal.py +0 -0
- {ragx_cli-0.1.0 → ragx_cli-0.1.1}/tests/test_vectors.py +0 -0
|
@@ -92,8 +92,8 @@ unreachable by vector search or rerank-alone, surfaced only via a hop-1 edge the
|
|
|
92
92
|
- `Config.set` rejects keys not in `DEFAULTS` — add new config keys to DEFAULTS first.
|
|
93
93
|
- Tests must not hit the network; one provider test self-skips when sentence-transformers
|
|
94
94
|
is installed. Pyright import errors in editors = interpreter not set to `.venv`.
|
|
95
|
-
- When running ragx against the wiki corpus: `cd` there, then
|
|
96
|
-
`uv run --project /Users/albert/projects/alber70g/ragx ragx-cli …` — and NEVER `git add`/commit
|
|
95
|
+
- When running ragx-cli against the wiki corpus: `cd` there, then
|
|
96
|
+
`uv run --project /Users/albert/projects/alber70g/ragx-cli ragx-cli …` — and NEVER `git add`/commit
|
|
97
97
|
from that directory (it's Albert's personal notes repo; `.ragx/` is gitignored there).
|
|
98
98
|
|
|
99
99
|
## What's next / deferred
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ragx module contracts — Phase 2–3 build
|
|
1
|
+
# ragx-cli module contracts — Phase 2–3 build
|
|
2
2
|
|
|
3
3
|
Same ground rules as CONTRACTS.md (read its "Global rules" and "Report protocol" — they apply
|
|
4
4
|
verbatim). Own ONLY your listed files; never modify shared/core files or other modules' files.
|
|
@@ -131,7 +131,7 @@ def evaluate(queries: list[dict], configs: list[tuple[str, QueryOptions]], query
|
|
|
131
131
|
|
|
132
132
|
# eval_cmd.py
|
|
133
133
|
def register(app: typer.Typer) -> None: ...
|
|
134
|
-
# ragx eval QUERIES_FILE [--json] [--top N] [--configs csv]
|
|
134
|
+
# ragx-cli eval QUERIES_FILE [--json] [--top N] [--configs csv]
|
|
135
135
|
# built-in configs: baseline (expand/graph/rerank all off), graph (only graph on),
|
|
136
136
|
# full (all on). Default: run all three.
|
|
137
137
|
# Constructs QueryOptions accordingly and query_fn from run_query + make_embedder(cfg) —
|
|
@@ -151,10 +151,10 @@ a monkeypatched evaluate/query_fn (no embeddings, no network).
|
|
|
151
151
|
|
|
152
152
|
```python
|
|
153
153
|
def register(app: typer.Typer) -> None: # app.add_typer(inspect_app, name="inspect")
|
|
154
|
-
# ragx inspect chunk ID [--json] -> chunk text, file, line/byte range + its edges
|
|
154
|
+
# ragx-cli inspect chunk ID [--json] -> chunk text, file, line/byte range + its edges
|
|
155
155
|
# (neighbor id, weight, neighbor's file path)
|
|
156
|
-
# ragx inspect file PATH [--json] -> file record + its chunks (id, line range, first 80 chars)
|
|
157
|
-
# ragx inspect neighbors ID [--json] -> store.neighbors(ID) enriched with each neighbor's file/lines
|
|
156
|
+
# ragx-cli inspect file PATH [--json] -> file record + its chunks (id, line range, first 80 chars)
|
|
157
|
+
# ragx-cli inspect neighbors ID [--json] -> store.neighbors(ID) enriched with each neighbor's file/lines
|
|
158
158
|
```
|
|
159
159
|
|
|
160
160
|
All read-only over Store (find root via require_root; no embeddings, no vectors file needed).
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ragx module contracts (Phase 0–1 build)
|
|
1
|
+
# ragx-cli module contracts (Phase 0–1 build)
|
|
2
2
|
|
|
3
3
|
Ground truth for the module-parallel build. Each module owns exactly the files listed for it.
|
|
4
4
|
**Do not create or edit files outside your module** — shared types live in `core/models.py`,
|
|
@@ -93,7 +93,7 @@ class OpenAICompatGenerator: # implements providers.base.Generator
|
|
|
93
93
|
# returns choices[0].message.content
|
|
94
94
|
|
|
95
95
|
# st_reranker.py — lazy `import sentence_transformers` inside __init__;
|
|
96
|
-
# ImportError -> RagxError("... install with: uv
|
|
96
|
+
# ImportError -> RagxError("... install with: uv tool install ragx-cli --with ragx-cli[rerank]")
|
|
97
97
|
class STReranker: # implements providers.base.Reranker
|
|
98
98
|
def __init__(self, model: str): ...
|
|
99
99
|
def score(self, query: str, texts: Sequence[str]) -> list[float]: ... # CrossEncoder.predict
|
|
@@ -205,11 +205,11 @@ def fail(msg: str, code: int = 2) -> NoReturn: ...
|
|
|
205
205
|
|
|
206
206
|
# app.py
|
|
207
207
|
app = typer.Typer(...)
|
|
208
|
-
# ragx init [path] -> write_default_config at path (default cwd); error (exit 2) if .ragx exists;
|
|
208
|
+
# ragx-cli init [path] -> write_default_config at path (default cwd); error (exit 2) if .ragx-cli exists;
|
|
209
209
|
# prints created config path
|
|
210
|
-
# ragx status [--json] -> root path, embedding model/provider, counts (files/chunks/edges) read via
|
|
210
|
+
# ragx-cli status [--json] -> root path, embedding model/provider, counts (files/chunks/edges) read via
|
|
211
211
|
# Store if index.db exists else zeros, schema "ragx.status.v1" in JSON mode
|
|
212
|
-
# ragx config get KEY / ragx config set KEY VALUE -> Config.get / Config.set + save
|
|
212
|
+
# ragx-cli config get KEY / ragx-cli config set KEY VALUE -> Config.get / Config.set + save
|
|
213
213
|
def main() -> None: ... # entry point declared in pyproject [project.scripts]
|
|
214
214
|
```
|
|
215
215
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ragx-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1
|
|
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
|
|
@@ -45,7 +45,7 @@ JSON schemas, deterministic exit codes, byte-exact source locations, and an `--e
|
|
|
45
45
|
that can justify every result via the exact graph path that produced it.
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
uv tool install ragx-cli
|
|
48
|
+
uv tool install ragx-cli --with ragx-cli[rerank] # install and use `ragx-cli`
|
|
49
49
|
ragx-cli init # create .ragx/ with config.toml next to your corpus
|
|
50
50
|
ragx-cli index # chunk -> embed -> HNSW + kNN similarity graph
|
|
51
51
|
ragx-cli query "why did we switch build tools?" --json --files-only
|
|
@@ -67,7 +67,7 @@ uses a local sentence-transformers cross-encoder (`ragx-cli[rerank]` extra). Eve
|
|
|
67
67
|
- [Using ragx-cli from a coding agent (CLAUDE.md / AGENTS.md)](#using-ragx-cli-from-a-coding-agent-claudemd--agentsmd)
|
|
68
68
|
- [Pointing ragx-cli at your LLM — local or online](#pointing-ragx-cli-at-your-llm--local-or-online)
|
|
69
69
|
- [Configuration](#configuration)
|
|
70
|
-
- [Features
|
|
70
|
+
- [Features \& roadmap](#features--roadmap)
|
|
71
71
|
|
|
72
72
|
|
|
73
73
|
## How it works
|
|
@@ -19,7 +19,7 @@ JSON schemas, deterministic exit codes, byte-exact source locations, and an `--e
|
|
|
19
19
|
that can justify every result via the exact graph path that produced it.
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
uv tool install ragx-cli
|
|
22
|
+
uv tool install ragx-cli --with ragx-cli[rerank] # install and use `ragx-cli`
|
|
23
23
|
ragx-cli init # create .ragx/ with config.toml next to your corpus
|
|
24
24
|
ragx-cli index # chunk -> embed -> HNSW + kNN similarity graph
|
|
25
25
|
ragx-cli query "why did we switch build tools?" --json --files-only
|
|
@@ -41,7 +41,7 @@ uses a local sentence-transformers cross-encoder (`ragx-cli[rerank]` extra). Eve
|
|
|
41
41
|
- [Using ragx-cli from a coding agent (CLAUDE.md / AGENTS.md)](#using-ragx-cli-from-a-coding-agent-claudemd--agentsmd)
|
|
42
42
|
- [Pointing ragx-cli at your LLM — local or online](#pointing-ragx-cli-at-your-llm--local-or-online)
|
|
43
43
|
- [Configuration](#configuration)
|
|
44
|
-
- [Features
|
|
44
|
+
- [Features \& roadmap](#features--roadmap)
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
## How it works
|
|
@@ -6,7 +6,7 @@ exists, so its effect on recall/MRR is measured against a stable baseline before
|
|
|
6
6
|
## Decisions
|
|
7
7
|
|
|
8
8
|
1. **Opt-in only.** Temporal signals never influence ranking by default. No δ-term in the default
|
|
9
|
-
scoring formula. All behavior is activated by explicit `ragx query` flags.
|
|
9
|
+
scoring formula. All behavior is activated by explicit `ragx-cli query` flags.
|
|
10
10
|
2. **Capabilities** (all three):
|
|
11
11
|
- **Hard filters:** `--since <date>` / `--until <date>` constrain candidates by document date.
|
|
12
12
|
- **Recency bias, directional:** a decay boost that is *configurable in direction* —
|
|
@@ -30,7 +30,7 @@ exists, so its effect on recall/MRR is measured against a stable baseline before
|
|
|
30
30
|
|
|
31
31
|
- Schema: `files.doc_date` (ISO date, nullable) + `files.date_source` → SQLite `user_version = 2`
|
|
32
32
|
migration. Backfill needs only a metadata pass (re-run date extraction per file) — **no
|
|
33
|
-
re-embedding required**; add e.g. `ragx index --refresh-dates`.
|
|
33
|
+
re-embedding required**; add e.g. `ragx-cli index --refresh-dates`.
|
|
34
34
|
- Chunks inherit their file's date (chunk-level dates from in-text mentions were considered and
|
|
35
35
|
parked — noisy, and most of the corpus is single-date documents).
|
|
36
36
|
- Filters apply before traversal (constrain seeds and admitted neighbors); bias applies after
|
|
@@ -53,13 +53,13 @@ Rationale: the entire retrieval ecosystem (FAISS/HNSW, sentence-transformers cro
|
|
|
53
53
|
## 3. CLI surface
|
|
54
54
|
|
|
55
55
|
```
|
|
56
|
-
ragx init [path] # create .ragx/, write default config.toml
|
|
57
|
-
ragx index [path] [--changed] # chunk, embed, build/update kNN graph
|
|
58
|
-
ragx query "..." [--json] [--top N] [--no-expand] [--no-graph] [--no-rerank]
|
|
56
|
+
ragx-cli init [path] # create .ragx/, write default config.toml
|
|
57
|
+
ragx-cli index [path] [--changed] # chunk, embed, build/update kNN graph
|
|
58
|
+
ragx-cli query "..." [--json] [--top N] [--no-expand] [--no-graph] [--no-rerank]
|
|
59
59
|
[--files-only] [--hops H] [--explain]
|
|
60
|
-
ragx inspect chunk <id> | file <path> | neighbors <id> # debug the graph
|
|
61
|
-
ragx status # index freshness, counts, config summary
|
|
62
|
-
ragx config get|set <key> [value]
|
|
60
|
+
ragx-cli inspect chunk <id> | file <path> | neighbors <id> # debug the graph
|
|
61
|
+
ragx-cli status # index freshness, counts, config summary
|
|
62
|
+
ragx-cli config get|set <key> [value]
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
Conventions for agent use: `--json` emits a single JSON document on stdout (schema versioned, `"schema": "ragx.query.v1"`); logs go to stderr; exit code 0 = success with results, 1 = success but empty, 2 = error. `query` also accepts the query on stdin when the argument is `-`.
|
|
@@ -74,7 +74,7 @@ Conventions for agent use: `--json` emits a single JSON document on stdout (sche
|
|
|
74
74
|
2. **Chunking.** Structure-aware where cheap: split Markdown on headings, code on function boundaries (tree-sitter optional, regex fallback), plain text by recursive character splitting. Defaults: ~800 tokens, 15% overlap. Every chunk records `file, byte_start, byte_end, line_start, line_end` so agents can jump to exact locations.
|
|
75
75
|
3. **Embedding.** Batch through the configured provider, applying document prefixes if the model requires them. Store vectors in HNSW; store chunk metadata in SQLite.
|
|
76
76
|
4. **Graph construction.** For every chunk, query HNSW for top-`k` neighbors (default k=8) above a similarity floor (default cosine ≥ 0.55, configurable). Write undirected weighted edges to SQLite (`edges(src, dst, weight)`), deduplicated. This is the entire "graph build" — one ANN pass over data already in memory.
|
|
77
|
-
5. **Incremental updates.** New/changed chunks: embed, insert, compute their edges, and recompute edges only for chunks that appear in the new chunks' neighbor lists. Deleted files: remove chunks, vectors (HNSW soft-delete + periodic `ragx index --compact`), and incident edges.
|
|
77
|
+
5. **Incremental updates.** New/changed chunks: embed, insert, compute their edges, and recompute edges only for chunks that appear in the new chunks' neighbor lists. Deleted files: remove chunks, vectors (HNSW soft-delete + periodic `ragx-cli index --compact`), and incident edges.
|
|
78
78
|
|
|
79
79
|
### 4.2 Query
|
|
80
80
|
|
|
@@ -96,11 +96,11 @@ Stages are individually skippable via flags so agents can trade quality for late
|
|
|
96
96
|
|
|
97
97
|
**Phase 2 — Similarity graph (1–2 days).** Edge construction during indexing, `inspect` commands, heat-propagation traversal in `query`, `--explain` output, incremental edge maintenance. Evaluate: recall@10 with graph on vs. off on a small labeled query set (~20 queries is enough to steer).
|
|
98
98
|
|
|
99
|
-
**Phase 3 — Expansion + rerank (1–2 days).** Multi-query/HyDE expansion stage, RRF fusion, cross-encoder reranker, combined scoring, `--no-*` flags. Add a tiny built-in eval harness: `ragx eval queries.jsonl` reporting recall@k / MRR per pipeline configuration, so parameter tuning (k, decay, floors, α/β/γ) is measurable instead of vibes.
|
|
99
|
+
**Phase 3 — Expansion + rerank (1–2 days).** Multi-query/HyDE expansion stage, RRF fusion, cross-encoder reranker, combined scoring, `--no-*` flags. Add a tiny built-in eval harness: `ragx-cli eval queries.jsonl` reporting recall@k / MRR per pipeline configuration, so parameter tuning (k, decay, floors, α/β/γ) is measurable instead of vibes.
|
|
100
100
|
|
|
101
101
|
**Phase 4 — Scale + communities (optional, 2–3 days).** Leiden community detection over the edge list; per-community extractive labels (top-TF-IDF terms — still no LLM required) or optional LLM summaries; `query --global` mode that routes through communities for corpus-level questions. Performance work: batch/parallel embedding, HNSW `ef` tuning, compaction.
|
|
102
102
|
|
|
103
|
-
**Phase 5 — MCP (later, deliberately deferred).** Because all query logic lives in a `ragx.core` library layer with the CLI as a thin shell, the MCP server is a second thin shell: `ragx serve --mcp` exposing `query`, `inspect`, `status` as tools over stdio. No refactor needed if the core/CLI split is respected from Phase 0 — that split is the one architectural rule to enforce early.
|
|
103
|
+
**Phase 5 — MCP (later, deliberately deferred).** Because all query logic lives in a `ragx.core` library layer with the CLI as a thin shell, the MCP server is a second thin shell: `ragx-cli serve --mcp` exposing `query`, `inspect`, `status` as tools over stdio. No refactor needed if the core/CLI split is respected from Phase 0 — that split is the one architectural rule to enforce early.
|
|
104
104
|
|
|
105
105
|
---
|
|
106
106
|
|
|
@@ -124,15 +124,15 @@ Stages are individually skippable via flags so agents can trade quality for late
|
|
|
124
124
|
1. **Hub chunks** (boilerplate, headers) attract many edges and dominate traversal. Mitigate: max-not-sum heat aggregation, per-node degree cap (drop edges beyond top-k both directions), optional stopword-density filter at chunking time.
|
|
125
125
|
2. **Similarity ≠ relevance.** Graph neighbors of a relevant chunk can be topically adjacent but useless. The query-floor filter during traversal and the cross-encoder rerank are the two guards; the eval harness (Phase 3) verifies they're working.
|
|
126
126
|
3. **HNSW deletes** degrade the index over time. Soft-delete + `--compact` rebuild; acceptable for corpora that change incrementally.
|
|
127
|
-
4. **Embedding model changes** invalidate everything. Store model name + dimension in the manifest; refuse to mix, offer `ragx index --rebuild`.
|
|
127
|
+
4. **Embedding model changes** invalidate everything. Store model name + dimension in the manifest; refuse to mix, offer `ragx-cli index --rebuild`.
|
|
128
128
|
5. **Agent misuse of long output.** Default `--top 8`, chunk text truncated to a configurable max in JSON output with `byte_start/byte_end` so agents fetch full text from the file themselves.
|
|
129
129
|
|
|
130
130
|
---
|
|
131
131
|
|
|
132
132
|
## 8. Definition of done (pre-MCP)
|
|
133
133
|
|
|
134
|
-
- `uvx ragx init && ragx index && ragx query "..." --json --files-only` works on a fresh repo with only Ollama running.
|
|
135
|
-
- Incremental `ragx index --changed` after editing one file touches only affected chunks/edges.
|
|
134
|
+
- `uvx ragx-cli init && ragx-cli index && ragx-cli query "..." --json --files-only` works on a fresh repo with only Ollama running.
|
|
135
|
+
- Incremental `ragx-cli index --changed` after editing one file touches only affected chunks/edges.
|
|
136
136
|
- Eval harness shows graph expansion improving recall@10 over the Phase 1 baseline on the reference query set, with rerank recovering precision.
|
|
137
137
|
- `--explain` can justify every returned chunk via seed → edge path → scores.
|
|
138
138
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.1"
|
|
@@ -54,7 +54,7 @@ def find_root(start: Path | None = None) -> Path | None:
|
|
|
54
54
|
def require_root(start: Path | None = None) -> Path:
|
|
55
55
|
root = find_root(start)
|
|
56
56
|
if root is None:
|
|
57
|
-
raise NotInitializedError("no .ragx/ found — run `ragx init` first")
|
|
57
|
+
raise NotInitializedError("no .ragx/ found — run `ragx-cli init` first")
|
|
58
58
|
return root
|
|
59
59
|
|
|
60
60
|
|
|
@@ -124,7 +124,7 @@ class Config:
|
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
def write_default_config(root: Path) -> Path:
|
|
127
|
-
"""Create .ragx/ with a default config.toml. Used by `ragx init`."""
|
|
127
|
+
"""Create .ragx/ with a default config.toml. Used by `ragx-cli init`."""
|
|
128
128
|
cfg = Config({k: dict(v) for k, v in DEFAULTS.items()})
|
|
129
129
|
cfg.save(root)
|
|
130
130
|
return config_path(root)
|
|
@@ -109,7 +109,7 @@ def _check_manifest(store: Store, embedder: Embedder, *, allow_rewrite: bool) ->
|
|
|
109
109
|
if prev and prev != embedder.model and not allow_rewrite:
|
|
110
110
|
raise ManifestMismatchError(
|
|
111
111
|
f"index was built with {prev!r} but config says {embedder.model!r}; "
|
|
112
|
-
"run a full `ragx index` to rebuild"
|
|
112
|
+
"run a full `ragx-cli index` to rebuild"
|
|
113
113
|
)
|
|
114
114
|
|
|
115
115
|
|
|
@@ -42,7 +42,7 @@ def _check_model(store: Store, embedder: Embedder) -> None:
|
|
|
42
42
|
if built_with != embedder.model:
|
|
43
43
|
raise RagxError(
|
|
44
44
|
f"index built with {built_with!r}, config says {embedder.model!r}; "
|
|
45
|
-
"run `ragx index` to rebuild"
|
|
45
|
+
"run `ragx-cli index` to rebuild"
|
|
46
46
|
)
|
|
47
47
|
|
|
48
48
|
|
|
@@ -33,7 +33,7 @@ def _resolve_api_key(cfg: Config, section: str) -> str | None:
|
|
|
33
33
|
|
|
34
34
|
def _resolve_base_url(cfg: Config, section: str) -> str:
|
|
35
35
|
"""Honor the conventional OPENAI_BASE_URL env var, but only while `<section>.base_url`
|
|
36
|
-
is still the built-in default — an explicit `ragx config set` always wins."""
|
|
36
|
+
is still the built-in default — an explicit `ragx-cli config set` always wins."""
|
|
37
37
|
base_url = cfg.get(f"{section}.base_url")
|
|
38
38
|
env_url = os.environ.get("OPENAI_BASE_URL")
|
|
39
39
|
if env_url and base_url == _DEFAULT_OPENAI_BASE_URL:
|
|
@@ -17,7 +17,7 @@ class STReranker:
|
|
|
17
17
|
from sentence_transformers import CrossEncoder
|
|
18
18
|
except ImportError as exc:
|
|
19
19
|
raise RagxError(
|
|
20
|
-
"sentence-transformers not installed — install with: uv
|
|
20
|
+
"sentence-transformers not installed — install with: uv tool install ragx-cli --with ragx-cli[rerank]"
|
|
21
21
|
) from exc
|
|
22
22
|
self.model = model
|
|
23
23
|
self._encoder = CrossEncoder(model)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.1.0"
|
|
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
|