ragrefine 0.2.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.
Files changed (37) hide show
  1. ragrefine-0.2.1/LICENSE +21 -0
  2. ragrefine-0.2.1/PKG-INFO +183 -0
  3. ragrefine-0.2.1/README.md +151 -0
  4. ragrefine-0.2.1/pyproject.toml +90 -0
  5. ragrefine-0.2.1/pyproject.toml.orig +71 -0
  6. ragrefine-0.2.1/src/ragrefine/__init__.py +14 -0
  7. ragrefine-0.2.1/src/ragrefine/_channels.py +16 -0
  8. ragrefine-0.2.1/src/ragrefine/config.py +27 -0
  9. ragrefine-0.2.1/src/ragrefine/errors.py +21 -0
  10. ragrefine-0.2.1/src/ragrefine/integrations/__init__.py +1 -0
  11. ragrefine-0.2.1/src/ragrefine/integrations/haystack/__init__.py +33 -0
  12. ragrefine-0.2.1/src/ragrefine/integrations/haystack/adapter.py +72 -0
  13. ragrefine-0.2.1/src/ragrefine/integrations/haystack/component.py +150 -0
  14. ragrefine-0.2.1/src/ragrefine/integrations/haystack/fixture.py +96 -0
  15. ragrefine-0.2.1/src/ragrefine/integrations/haystack/pipeline.py +104 -0
  16. ragrefine-0.2.1/src/ragrefine/integrations/haystack/prompt.py +17 -0
  17. ragrefine-0.2.1/src/ragrefine/models.py +52 -0
  18. ragrefine-0.2.1/src/ragrefine/py.typed +0 -0
  19. ragrefine-0.2.1/src/ragrefine/query/__init__.py +18 -0
  20. ragrefine-0.2.1/src/ragrefine/query/normalize.py +34 -0
  21. ragrefine-0.2.1/src/ragrefine/query/patterns.py +132 -0
  22. ragrefine-0.2.1/src/ragrefine/ranking/__init__.py +24 -0
  23. ragrefine-0.2.1/src/ragrefine/ranking/lexical.py +97 -0
  24. ragrefine-0.2.1/src/ragrefine/ranking/patterns.py +153 -0
  25. ragrefine-0.2.1/src/ragrefine/ranking/rrf.py +87 -0
  26. ragrefine-0.2.1/src/ragrefine/ranking/types.py +25 -0
  27. ragrefine-0.2.1/src/ragrefine/refiner.py +516 -0
  28. ragrefine-0.2.1/src/ragrefine/rerank/__init__.py +6 -0
  29. ragrefine-0.2.1/src/ragrefine/rerank/base.py +30 -0
  30. ragrefine-0.2.1/src/ragrefine/rerank/sentence_transformers.py +133 -0
  31. ragrefine-0.2.1/src/ragrefine/results.py +20 -0
  32. ragrefine-0.2.1/src/ragrefine/selection/__init__.py +27 -0
  33. ragrefine-0.2.1/src/ragrefine/selection/deduplicate.py +142 -0
  34. ragrefine-0.2.1/src/ragrefine/selection/selector.py +126 -0
  35. ragrefine-0.2.1/src/ragrefine/selection/tokens.py +10 -0
  36. ragrefine-0.2.1/src/ragrefine/tracing/__init__.py +5 -0
  37. ragrefine-0.2.1/src/ragrefine/tracing/models.py +22 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Atharva Dharmadhikari
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,183 @@
1
+ Metadata-Version: 2.4
2
+ Name: ragrefine
3
+ Version: 0.2.1
4
+ Summary: Retriever-agnostic post-retrieval refinement for RAG candidates
5
+ Keywords: rag,retrieval,reranking,information-retrieval,llm
6
+ Author: Atharva Dharmadhikari
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Classifier: Topic :: Text Processing :: Indexing
16
+ Classifier: Typing :: Typed
17
+ Requires-Dist: beir==2.2.0 ; extra == 'beir'
18
+ Requires-Dist: haystack-ai==2.31.0 ; extra == 'haystack'
19
+ Requires-Dist: ragas==0.4.3 ; extra == 'ragas'
20
+ Requires-Dist: langchain-openai>=0.2.0,<1.0 ; extra == 'ragas'
21
+ Requires-Dist: sentence-transformers>=6.0.0,<7 ; extra == 'rerank'
22
+ Requires-Python: >=3.12
23
+ Project-URL: Homepage, https://github.com/Atharva01/ragrefine
24
+ Project-URL: Repository, https://github.com/Atharva01/ragrefine
25
+ Project-URL: Changelog, https://github.com/Atharva01/ragrefine/blob/main/CHANGELOG.md
26
+ Project-URL: Issues, https://github.com/Atharva01/ragrefine/issues
27
+ Provides-Extra: beir
28
+ Provides-Extra: haystack
29
+ Provides-Extra: ragas
30
+ Provides-Extra: rerank
31
+ Description-Content-Type: text/markdown
32
+
33
+ # ragrefine
34
+
35
+ **Evidence-first post-retrieval refinement for RAG systems.**
36
+
37
+ [![CI](https://github.com/Atharva01/ragrefine/actions/workflows/ci.yml/badge.svg)](https://github.com/Atharva01/ragrefine/actions/workflows/ci.yml)
38
+ [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/)
39
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
40
+
41
+ `ragrefine` improves an existing retriever's candidate set before it reaches an
42
+ LLM. It reranks, fuses, deduplicates, and selects context while preserving the
43
+ original evidence and recording an auditable trace.
44
+
45
+ ```text
46
+ retriever -> Top-N candidates -> ragrefine -> refined Top-K + trace -> LLM
47
+ ```
48
+
49
+ The core library is framework- and retriever-agnostic. Haystack support is
50
+ available as an optional integration.
51
+
52
+ ## Core deliverables
53
+
54
+ | Capability | Delivered behaviour |
55
+ |---|---|
56
+ | Candidate contract | Immutable candidates retain IDs, text, metadata, retrieval rank, and retrieval score |
57
+ | Ranking channels | Independent original, neural, lexical, and configurable pattern rankings over the same candidate pool |
58
+ | Rank fusion | Deterministic reciprocal-rank fusion without mixing incompatible raw-score scales |
59
+ | Context refinement | Exact/near-duplicate suppression and rank-preserving Top-K/token-budget selection |
60
+ | Traceability | Per-channel evidence, fusion contributions, stage timings, configuration, and explicit failure records |
61
+ | Neural reranking | Optional SentenceTransformers CrossEncoder adapter with batched inference |
62
+ | Haystack integration | Serializable component profiles and a retriever-to-generator pipeline builder |
63
+ | Evaluation | Frozen BEIR candidate pools, checksummed artifacts, reproducibility commands, and a paired Ragas harness |
64
+
65
+ Output candidates always originate from the supplied input pool; `ragrefine`
66
+ does not invent or rewrite evidence.
67
+
68
+ ## Quick start
69
+
70
+ Python 3.12+ is required. From this checkout:
71
+
72
+ ```bash
73
+ uv sync
74
+ ```
75
+
76
+ ```python
77
+ from ragrefine import Candidate, CandidateSet, Refiner
78
+
79
+ candidates = CandidateSet(
80
+ name="my-retriever",
81
+ candidates=(
82
+ Candidate(
83
+ id="doc-1",
84
+ text="Python 3.12 improves f-string parsing.",
85
+ retrieval_rank=1,
86
+ retrieval_score=0.91,
87
+ ),
88
+ Candidate(
89
+ id="doc-2",
90
+ text="Python 3.11 introduced exception groups.",
91
+ retrieval_rank=2,
92
+ retrieval_score=0.84,
93
+ ),
94
+ ),
95
+ )
96
+
97
+ result = Refiner().refine(
98
+ query="Which Python version improves f-string parsing?",
99
+ candidate_set=candidates,
100
+ top_k=1,
101
+ )
102
+
103
+ print(result.candidates[0].candidate.id)
104
+ print(result.trace)
105
+ ```
106
+
107
+ `Refiner()` preserves the original ranking. Explicit `RefinerConfig` settings
108
+ enable lexical, pattern, neural, or fused profiles. See the
109
+ [technical design](TECHNICAL_DESIGN.md) for the configuration contract.
110
+
111
+ ## Haystack integration
112
+
113
+ ```bash
114
+ uv sync --extra haystack
115
+ ```
116
+
117
+ The optional integration provides document conversion, a serializable
118
+ `RagRefineComponent`, registered refiner profiles, prompt construction, and a
119
+ complete Haystack pipeline builder. The [RAG pipeline guide](docs/rag-pipeline-guide.md)
120
+ contains the runnable recipe and customization points.
121
+
122
+ ## Evaluation summary
123
+
124
+ Post-retrieval comparisons reuse the same frozen first-stage Top-50 candidates.
125
+ Retrieval is not regenerated between profiles, and candidate-pool Recall@50 is
126
+ a fixed ceiling rather than a refinement gain.
127
+
128
+ | Experiment | SciFact result | Decision |
129
+ |---|---:|---|
130
+ | B0 — frozen dense baseline | nDCG@5 0.4592 | Baseline |
131
+ | B1-reference — MiniLM-L6/CUDA | nDCG@5 **0.6262** | Retained neural profile |
132
+ | B1-light — TinyBERT-L2/CPU | nDCG@5 **0.6112** | Retained measured profile |
133
+ | B2-L — lexical/CPU | nDCG@5 **0.5432** | Retained lightweight profile |
134
+ | B2-P — patterns/CPU | nDCG@5 0.4559 | Not retained |
135
+ | B3 — equal-weight fusion | Best profile nDCG@5 0.5715 | Not retained; below B1-reference |
136
+
137
+ The end-to-end Ragas A/B used 13 paired DeepSeek queries. It is statistically
138
+ inconclusive: the positive directional score differences have 95% paired
139
+ bootstrap confidence intervals spanning zero, and both context metrics are
140
+ saturated at 1.0. The run establishes neither an end-to-end benefit nor a
141
+ regression. See the [retained A/B report](benchmarks/results/haystack-ragas-analysis-v1/ragas-report.md).
142
+
143
+ Machine-readable artifacts are the source of truth. No experiment is described
144
+ as improved unless its recorded measurements support that claim.
145
+
146
+ ## Documentation
147
+
148
+ Detailed material removed from this README remains in the repository's focused
149
+ documents:
150
+
151
+ - [Product requirements](AI_PRD.md) — supported scope and product boundary
152
+ - [Technical hypotheses](TECHNICAL_HYPOTHESIS.md) — testable claims and current evidence
153
+ - [Technical design](TECHNICAL_DESIGN.md) — architecture, configuration, selection, and tracing contracts
154
+ - [Evaluation contract](docs/evaluation-contract-v0.1.md) — frozen-pool rules, metrics, profiles, and reporting policy
155
+ - [Benchmark guide](docs/benchmark-baseline.md) — execution and reproduction commands
156
+ - [Retained artifact manifest](benchmarks/artifacts/README.md) — checksummed benchmark inputs and verification
157
+ - [Haystack pipeline guide](docs/rag-pipeline-guide.md) — integration and serialization
158
+ - [Ragas evaluation guide](docs/haystack-ragas-evaluation.md) — paired A/B design and analysis
159
+ - [v0.2 release record](docs/v0.2-release.md) — delivered scope, validation, and limitations
160
+
161
+ ## Scope
162
+
163
+ `ragrefine` owns post-retrieval candidate refinement, context selection, and
164
+ tracing. It deliberately does not own ingestion, parsing, chunking, embeddings,
165
+ vector databases, first-stage retrieval, LLM generation, agents, or deployment.
166
+
167
+ ## Development
168
+
169
+ ```bash
170
+ uv sync --extra haystack --extra ragas
171
+ uv run ruff check .
172
+ uv run ruff format --check .
173
+ uv run mypy src/
174
+ uv run pytest
175
+ uv build
176
+ ```
177
+
178
+ Heavy model and benchmark dependencies remain optional so the core package has
179
+ no runtime dependencies.
180
+
181
+ ## License
182
+
183
+ [MIT](LICENSE)
@@ -0,0 +1,151 @@
1
+ # ragrefine
2
+
3
+ **Evidence-first post-retrieval refinement for RAG systems.**
4
+
5
+ [![CI](https://github.com/Atharva01/ragrefine/actions/workflows/ci.yml/badge.svg)](https://github.com/Atharva01/ragrefine/actions/workflows/ci.yml)
6
+ [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
8
+
9
+ `ragrefine` improves an existing retriever's candidate set before it reaches an
10
+ LLM. It reranks, fuses, deduplicates, and selects context while preserving the
11
+ original evidence and recording an auditable trace.
12
+
13
+ ```text
14
+ retriever -> Top-N candidates -> ragrefine -> refined Top-K + trace -> LLM
15
+ ```
16
+
17
+ The core library is framework- and retriever-agnostic. Haystack support is
18
+ available as an optional integration.
19
+
20
+ ## Core deliverables
21
+
22
+ | Capability | Delivered behaviour |
23
+ |---|---|
24
+ | Candidate contract | Immutable candidates retain IDs, text, metadata, retrieval rank, and retrieval score |
25
+ | Ranking channels | Independent original, neural, lexical, and configurable pattern rankings over the same candidate pool |
26
+ | Rank fusion | Deterministic reciprocal-rank fusion without mixing incompatible raw-score scales |
27
+ | Context refinement | Exact/near-duplicate suppression and rank-preserving Top-K/token-budget selection |
28
+ | Traceability | Per-channel evidence, fusion contributions, stage timings, configuration, and explicit failure records |
29
+ | Neural reranking | Optional SentenceTransformers CrossEncoder adapter with batched inference |
30
+ | Haystack integration | Serializable component profiles and a retriever-to-generator pipeline builder |
31
+ | Evaluation | Frozen BEIR candidate pools, checksummed artifacts, reproducibility commands, and a paired Ragas harness |
32
+
33
+ Output candidates always originate from the supplied input pool; `ragrefine`
34
+ does not invent or rewrite evidence.
35
+
36
+ ## Quick start
37
+
38
+ Python 3.12+ is required. From this checkout:
39
+
40
+ ```bash
41
+ uv sync
42
+ ```
43
+
44
+ ```python
45
+ from ragrefine import Candidate, CandidateSet, Refiner
46
+
47
+ candidates = CandidateSet(
48
+ name="my-retriever",
49
+ candidates=(
50
+ Candidate(
51
+ id="doc-1",
52
+ text="Python 3.12 improves f-string parsing.",
53
+ retrieval_rank=1,
54
+ retrieval_score=0.91,
55
+ ),
56
+ Candidate(
57
+ id="doc-2",
58
+ text="Python 3.11 introduced exception groups.",
59
+ retrieval_rank=2,
60
+ retrieval_score=0.84,
61
+ ),
62
+ ),
63
+ )
64
+
65
+ result = Refiner().refine(
66
+ query="Which Python version improves f-string parsing?",
67
+ candidate_set=candidates,
68
+ top_k=1,
69
+ )
70
+
71
+ print(result.candidates[0].candidate.id)
72
+ print(result.trace)
73
+ ```
74
+
75
+ `Refiner()` preserves the original ranking. Explicit `RefinerConfig` settings
76
+ enable lexical, pattern, neural, or fused profiles. See the
77
+ [technical design](TECHNICAL_DESIGN.md) for the configuration contract.
78
+
79
+ ## Haystack integration
80
+
81
+ ```bash
82
+ uv sync --extra haystack
83
+ ```
84
+
85
+ The optional integration provides document conversion, a serializable
86
+ `RagRefineComponent`, registered refiner profiles, prompt construction, and a
87
+ complete Haystack pipeline builder. The [RAG pipeline guide](docs/rag-pipeline-guide.md)
88
+ contains the runnable recipe and customization points.
89
+
90
+ ## Evaluation summary
91
+
92
+ Post-retrieval comparisons reuse the same frozen first-stage Top-50 candidates.
93
+ Retrieval is not regenerated between profiles, and candidate-pool Recall@50 is
94
+ a fixed ceiling rather than a refinement gain.
95
+
96
+ | Experiment | SciFact result | Decision |
97
+ |---|---:|---|
98
+ | B0 — frozen dense baseline | nDCG@5 0.4592 | Baseline |
99
+ | B1-reference — MiniLM-L6/CUDA | nDCG@5 **0.6262** | Retained neural profile |
100
+ | B1-light — TinyBERT-L2/CPU | nDCG@5 **0.6112** | Retained measured profile |
101
+ | B2-L — lexical/CPU | nDCG@5 **0.5432** | Retained lightweight profile |
102
+ | B2-P — patterns/CPU | nDCG@5 0.4559 | Not retained |
103
+ | B3 — equal-weight fusion | Best profile nDCG@5 0.5715 | Not retained; below B1-reference |
104
+
105
+ The end-to-end Ragas A/B used 13 paired DeepSeek queries. It is statistically
106
+ inconclusive: the positive directional score differences have 95% paired
107
+ bootstrap confidence intervals spanning zero, and both context metrics are
108
+ saturated at 1.0. The run establishes neither an end-to-end benefit nor a
109
+ regression. See the [retained A/B report](benchmarks/results/haystack-ragas-analysis-v1/ragas-report.md).
110
+
111
+ Machine-readable artifacts are the source of truth. No experiment is described
112
+ as improved unless its recorded measurements support that claim.
113
+
114
+ ## Documentation
115
+
116
+ Detailed material removed from this README remains in the repository's focused
117
+ documents:
118
+
119
+ - [Product requirements](AI_PRD.md) — supported scope and product boundary
120
+ - [Technical hypotheses](TECHNICAL_HYPOTHESIS.md) — testable claims and current evidence
121
+ - [Technical design](TECHNICAL_DESIGN.md) — architecture, configuration, selection, and tracing contracts
122
+ - [Evaluation contract](docs/evaluation-contract-v0.1.md) — frozen-pool rules, metrics, profiles, and reporting policy
123
+ - [Benchmark guide](docs/benchmark-baseline.md) — execution and reproduction commands
124
+ - [Retained artifact manifest](benchmarks/artifacts/README.md) — checksummed benchmark inputs and verification
125
+ - [Haystack pipeline guide](docs/rag-pipeline-guide.md) — integration and serialization
126
+ - [Ragas evaluation guide](docs/haystack-ragas-evaluation.md) — paired A/B design and analysis
127
+ - [v0.2 release record](docs/v0.2-release.md) — delivered scope, validation, and limitations
128
+
129
+ ## Scope
130
+
131
+ `ragrefine` owns post-retrieval candidate refinement, context selection, and
132
+ tracing. It deliberately does not own ingestion, parsing, chunking, embeddings,
133
+ vector databases, first-stage retrieval, LLM generation, agents, or deployment.
134
+
135
+ ## Development
136
+
137
+ ```bash
138
+ uv sync --extra haystack --extra ragas
139
+ uv run ruff check .
140
+ uv run ruff format --check .
141
+ uv run mypy src/
142
+ uv run pytest
143
+ uv build
144
+ ```
145
+
146
+ Heavy model and benchmark dependencies remain optional so the core package has
147
+ no runtime dependencies.
148
+
149
+ ## License
150
+
151
+ [MIT](LICENSE)
@@ -0,0 +1,90 @@
1
+ [project]
2
+ name = "ragrefine"
3
+ version = "0.2.1"
4
+ description = "Retriever-agnostic post-retrieval refinement for RAG candidates"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ keywords = [
10
+ "rag",
11
+ "retrieval",
12
+ "reranking",
13
+ "information-retrieval",
14
+ "llm",
15
+ ]
16
+ classifiers = [
17
+ "Development Status :: 4 - Beta",
18
+ "Intended Audience :: Developers",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3 :: Only",
22
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
23
+ "Topic :: Text Processing :: Indexing",
24
+ "Typing :: Typed",
25
+ ]
26
+ dependencies = []
27
+
28
+ [[project.authors]]
29
+ name = "Atharva Dharmadhikari"
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/Atharva01/ragrefine"
33
+ Repository = "https://github.com/Atharva01/ragrefine"
34
+ Changelog = "https://github.com/Atharva01/ragrefine/blob/main/CHANGELOG.md"
35
+ Issues = "https://github.com/Atharva01/ragrefine/issues"
36
+
37
+ [project.optional-dependencies]
38
+ beir = ["beir==2.2.0"]
39
+ rerank = ["sentence-transformers>=6.0.0,<7"]
40
+ haystack = ["haystack-ai==2.31.0"]
41
+ ragas = [
42
+ "ragas==0.4.3",
43
+ "langchain-openai>=0.2.0,<1.0",
44
+ ]
45
+
46
+ [build-system]
47
+ requires = ["uv_build>=0.12.0,<0.13.0"]
48
+ build-backend = "uv_build"
49
+
50
+ [dependency-groups]
51
+ dev = [
52
+ "hypothesis>=6.165.10",
53
+ "mypy>=2.3.1",
54
+ "pytest>=9.1.1",
55
+ "pytest-cov>=7.1.0",
56
+ "ruff>=0.16.3",
57
+ ]
58
+
59
+ [tool.ruff]
60
+ extend-exclude = ["docs"]
61
+ line-length = 88
62
+ target-version = "py312"
63
+
64
+ [tool.ruff.lint]
65
+ select = [
66
+ "E",
67
+ "F",
68
+ "I",
69
+ "UP",
70
+ ]
71
+
72
+ [tool.mypy]
73
+ files = ["src"]
74
+ python_version = "3.12"
75
+ strict = true
76
+
77
+ [[tool.mypy.overrides]]
78
+ module = [
79
+ "huggingface_hub",
80
+ "sentence_transformers",
81
+ ]
82
+ ignore_missing_imports = true
83
+
84
+ [tool.pytest.ini_options]
85
+ testpaths = ["tests"]
86
+ pythonpath = ["."]
87
+ markers = [
88
+ "integration: tests that require integration infrastructure",
89
+ "model: tests that require model downloads or inference",
90
+ ]
@@ -0,0 +1,71 @@
1
+ [project]
2
+ name = "ragrefine"
3
+ version = "0.2.1"
4
+ description = "Retriever-agnostic post-retrieval refinement for RAG candidates"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ authors = [{ name = "Atharva Dharmadhikari" }]
10
+ keywords = ["rag", "retrieval", "reranking", "information-retrieval", "llm"]
11
+ classifiers = [
12
+ "Development Status :: 4 - Beta",
13
+ "Intended Audience :: Developers",
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3.12",
16
+ "Programming Language :: Python :: 3 :: Only",
17
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
18
+ "Topic :: Text Processing :: Indexing",
19
+ "Typing :: Typed",
20
+ ]
21
+ dependencies = []
22
+
23
+ [project.urls]
24
+ Homepage = "https://github.com/Atharva01/ragrefine"
25
+ Repository = "https://github.com/Atharva01/ragrefine"
26
+ Changelog = "https://github.com/Atharva01/ragrefine/blob/main/CHANGELOG.md"
27
+ Issues = "https://github.com/Atharva01/ragrefine/issues"
28
+
29
+ [project.optional-dependencies]
30
+ beir = ["beir==2.2.0"]
31
+ rerank = ["sentence-transformers>=6.0.0,<7"]
32
+ haystack = ["haystack-ai==2.31.0"]
33
+ ragas = ["ragas==0.4.3", "langchain-openai>=0.2.0,<1.0"]
34
+
35
+ [build-system]
36
+ requires = ["uv_build>=0.12.0,<0.13.0"]
37
+ build-backend = "uv_build"
38
+
39
+ [dependency-groups]
40
+ dev = [
41
+ "hypothesis>=6.165.10",
42
+ "mypy>=2.3.1",
43
+ "pytest>=9.1.1",
44
+ "pytest-cov>=7.1.0",
45
+ "ruff>=0.16.3",
46
+ ]
47
+
48
+ [tool.ruff]
49
+ extend-exclude = ["docs"]
50
+ line-length = 88
51
+ target-version = "py312"
52
+
53
+ [tool.ruff.lint]
54
+ select = ["E", "F", "I", "UP"]
55
+
56
+ [tool.mypy]
57
+ files = ["src"]
58
+ python_version = "3.12"
59
+ strict = true
60
+
61
+ [[tool.mypy.overrides]]
62
+ module = ["huggingface_hub", "sentence_transformers"]
63
+ ignore_missing_imports = true
64
+
65
+ [tool.pytest.ini_options]
66
+ testpaths = ["tests"]
67
+ pythonpath = ["."]
68
+ markers = [
69
+ "integration: tests that require integration infrastructure",
70
+ "model: tests that require model downloads or inference",
71
+ ]
@@ -0,0 +1,14 @@
1
+ """Retriever-agnostic post-retrieval refinement for RAG candidate sets."""
2
+
3
+ from ragrefine.config import RefinerConfig
4
+ from ragrefine.models import Candidate, CandidateSet
5
+ from ragrefine.refiner import Refiner
6
+ from ragrefine.results import RefinementResult
7
+
8
+ __all__ = [
9
+ "Candidate",
10
+ "CandidateSet",
11
+ "RefinerConfig",
12
+ "RefinementResult",
13
+ "Refiner",
14
+ ]
@@ -0,0 +1,16 @@
1
+ """Private channel execution result used only by :mod:`ragrefine.refiner`."""
2
+
3
+ from collections.abc import Mapping
4
+ from dataclasses import dataclass, field
5
+
6
+ from ragrefine.models import Candidate
7
+
8
+
9
+ @dataclass(frozen=True, slots=True)
10
+ class _ChannelResult:
11
+ """One successful channel execution over the unchanged input candidate pool."""
12
+
13
+ name: str
14
+ ranking: tuple[Candidate, ...]
15
+ evidence: Mapping[str, Mapping[str, object]]
16
+ metadata: Mapping[str, object] = field(default_factory=dict)
@@ -0,0 +1,27 @@
1
+ """Public configuration for deterministic refinement channels."""
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+
6
+ @dataclass(frozen=True, slots=True)
7
+ class ChannelConfig:
8
+ """Whether to run one channel, require success, and its fusion weight."""
9
+
10
+ enabled: bool = False
11
+ required: bool = True
12
+ weight: float = 1.0
13
+
14
+ def __post_init__(self) -> None:
15
+ if self.weight < 0:
16
+ raise ValueError("channel weight must be non-negative")
17
+
18
+
19
+ @dataclass(frozen=True, slots=True)
20
+ class RefinerConfig:
21
+ """Explicit independent channel configuration for B0 through B3 modes."""
22
+
23
+ original: ChannelConfig = field(default_factory=lambda: ChannelConfig(enabled=True))
24
+ neural: ChannelConfig = field(default_factory=ChannelConfig)
25
+ lexical: ChannelConfig = field(default_factory=ChannelConfig)
26
+ pattern: ChannelConfig = field(default_factory=ChannelConfig)
27
+ fusion_enabled: bool = False
@@ -0,0 +1,21 @@
1
+ """Typed package exceptions for refinement failures."""
2
+
3
+
4
+ class RagRefineError(Exception):
5
+ """Base exception for explicit ragrefine failures."""
6
+
7
+
8
+ class RerankerError(RagRefineError):
9
+ """Raised when neural reranking cannot complete safely."""
10
+
11
+
12
+ class PatternError(RagRefineError):
13
+ """Raised when configured pattern processing is invalid or unsafe."""
14
+
15
+
16
+ class ChannelExecutionError(RagRefineError):
17
+ """Raised when a required ranking channel cannot complete."""
18
+
19
+
20
+ class MultipleActiveChannelsError(RagRefineError):
21
+ """Raised when independent rankings need fusion but it is disabled."""
@@ -0,0 +1 @@
1
+ """Optional framework integrations for ragrefine."""
@@ -0,0 +1,33 @@
1
+ """Optional Haystack integration for ragrefine.
2
+
3
+ Installed with ``ragrefine[haystack]``. Provides the document adapter,
4
+ ``RagRefineComponent`` with serializable refiner profiles, the prompt builder,
5
+ a frozen retrieval fixture, and a ready-made RAG pipeline builder.
6
+ """
7
+
8
+ from ragrefine.integrations.haystack.adapter import HaystackDocumentAdapter
9
+ from ragrefine.integrations.haystack.component import (
10
+ RagRefineComponent,
11
+ refiner_for_profile,
12
+ register_refiner_factory,
13
+ )
14
+ from ragrefine.integrations.haystack.fixture import FrozenHaystackFixture
15
+ from ragrefine.integrations.haystack.pipeline import (
16
+ ChatPromptAdapter,
17
+ build_rag_pipeline,
18
+ demo_documents,
19
+ )
20
+ from ragrefine.integrations.haystack.prompt import PROMPT_TEMPLATE, prompt_builder
21
+
22
+ __all__ = [
23
+ "ChatPromptAdapter",
24
+ "FrozenHaystackFixture",
25
+ "HaystackDocumentAdapter",
26
+ "PROMPT_TEMPLATE",
27
+ "RagRefineComponent",
28
+ "build_rag_pipeline",
29
+ "demo_documents",
30
+ "prompt_builder",
31
+ "refiner_for_profile",
32
+ "register_refiner_factory",
33
+ ]