haiku.rag 0.5.1__tar.gz → 0.5.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of haiku.rag might be problematic. Click here for more details.

Files changed (79) hide show
  1. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/PKG-INFO +4 -3
  2. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/docs/configuration.md +26 -4
  3. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/pyproject.toml +3 -3
  4. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/app.py +2 -2
  5. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/cli.py +2 -2
  6. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/client.py +4 -3
  7. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/config.py +2 -3
  8. haiku_rag-0.5.2/src/haiku/rag/reranking/__init__.py +40 -0
  9. haiku_rag-0.5.2/src/haiku/rag/reranking/ollama.py +84 -0
  10. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_reranker.py +25 -8
  11. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/uv.lock +10 -8
  12. haiku_rag-0.5.1/src/haiku/rag/reranking/__init__.py +0 -37
  13. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/.github/FUNDING.yml +0 -0
  14. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/.github/workflows/build-docs.yml +0 -0
  15. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/.github/workflows/build-publish.yml +0 -0
  16. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/.gitignore +0 -0
  17. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/.pre-commit-config.yaml +0 -0
  18. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/.python-version +0 -0
  19. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/LICENSE +0 -0
  20. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/README.md +0 -0
  21. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/docs/benchmarks.md +0 -0
  22. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/docs/cli.md +0 -0
  23. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/docs/index.md +0 -0
  24. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/docs/installation.md +0 -0
  25. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/docs/mcp.md +0 -0
  26. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/docs/python.md +0 -0
  27. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/docs/server.md +0 -0
  28. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/mkdocs.yml +0 -0
  29. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/__init__.py +0 -0
  30. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/chunker.py +0 -0
  31. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/embeddings/__init__.py +0 -0
  32. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/embeddings/base.py +0 -0
  33. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/embeddings/ollama.py +0 -0
  34. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/embeddings/openai.py +0 -0
  35. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/embeddings/voyageai.py +0 -0
  36. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/logging.py +0 -0
  37. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/mcp.py +0 -0
  38. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/monitor.py +0 -0
  39. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/qa/__init__.py +0 -0
  40. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/qa/anthropic.py +0 -0
  41. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/qa/base.py +0 -0
  42. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/qa/ollama.py +0 -0
  43. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/qa/openai.py +0 -0
  44. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/qa/prompts.py +0 -0
  45. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/reader.py +0 -0
  46. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/reranking/base.py +0 -0
  47. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/reranking/cohere.py +0 -0
  48. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/reranking/mxbai.py +0 -0
  49. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/__init__.py +0 -0
  50. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/engine.py +0 -0
  51. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/models/__init__.py +0 -0
  52. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/models/chunk.py +0 -0
  53. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/models/document.py +0 -0
  54. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/repositories/__init__.py +0 -0
  55. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/repositories/base.py +0 -0
  56. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/repositories/chunk.py +0 -0
  57. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/repositories/document.py +0 -0
  58. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/repositories/settings.py +0 -0
  59. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/upgrades/__init__.py +0 -0
  60. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/store/upgrades/v0_3_4.py +0 -0
  61. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/src/haiku/rag/utils.py +0 -0
  62. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/__init__.py +0 -0
  63. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/conftest.py +0 -0
  64. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/generate_benchmark_db.py +0 -0
  65. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/llm_judge.py +0 -0
  66. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_app.py +0 -0
  67. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_chunk.py +0 -0
  68. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_chunker.py +0 -0
  69. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_cli.py +0 -0
  70. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_client.py +0 -0
  71. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_document.py +0 -0
  72. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_embedder.py +0 -0
  73. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_monitor.py +0 -0
  74. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_qa.py +0 -0
  75. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_reader.py +0 -0
  76. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_rebuild.py +0 -0
  77. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_search.py +0 -0
  78. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_settings.py +0 -0
  79. {haiku_rag-0.5.1 → haiku_rag-0.5.2}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haiku.rag
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: Retrieval Augmented Generation (RAG) with SQLite
5
5
  Author-email: Yiorgis Gozadinos <ggozadinos@gmail.com>
6
6
  License: MIT
@@ -21,8 +21,7 @@ Requires-Python: >=3.11
21
21
  Requires-Dist: docling>=2.15.0
22
22
  Requires-Dist: fastmcp>=2.8.1
23
23
  Requires-Dist: httpx>=0.28.1
24
- Requires-Dist: mxbai-rerank>=0.1.6
25
- Requires-Dist: ollama>=0.5.1
24
+ Requires-Dist: ollama>=0.5.3
26
25
  Requires-Dist: pydantic>=2.11.7
27
26
  Requires-Dist: python-dotenv>=1.1.0
28
27
  Requires-Dist: rich>=14.0.0
@@ -34,6 +33,8 @@ Provides-Extra: anthropic
34
33
  Requires-Dist: anthropic>=0.56.0; extra == 'anthropic'
35
34
  Provides-Extra: cohere
36
35
  Requires-Dist: cohere>=5.16.1; extra == 'cohere'
36
+ Provides-Extra: mxbai
37
+ Requires-Dist: mxbai-rerank>=0.1.6; extra == 'mxbai'
37
38
  Provides-Extra: openai
38
39
  Requires-Dist: openai>=1.0.0; extra == 'openai'
39
40
  Provides-Extra: voyageai
@@ -105,15 +105,37 @@ ANTHROPIC_API_KEY="your-api-key"
105
105
 
106
106
  ## Reranking
107
107
 
108
- Reranking is **enabled by default** and improves search quality by re-ordering the initial search results using specialized models. When enabled, the system retrieves more candidates (3x the requested limit) and then reranks them to return the most relevant results.
108
+ Reranking improves search quality by re-ordering the initial search results using specialized models. When enabled, the system retrieves more candidates (3x the requested limit) and then reranks them to return the most relevant results.
109
109
 
110
- If you use the default reranked (running locally), it can slow down searching significantly. To disable reranking for faster searches:
110
+ Reranking is **automatically enabled** by default using Ollama, or if you install the appropriate reranking provider package.
111
+
112
+ ### Disabling Reranking
113
+
114
+ To disable reranking completely for faster searches:
111
115
 
112
116
  ```bash
113
- RERANK=false
117
+ RERANK_PROVIDER=""
114
118
  ```
115
119
 
116
- ### MixedBread AI (Default)
120
+ ### Ollama (Default)
121
+
122
+ Ollama reranking uses LLMs with structured output to rank documents by relevance:
123
+
124
+ ```bash
125
+ RERANK_PROVIDER="ollama"
126
+ RERANK_MODEL="qwen3:1.7b" # or any model that supports structured output
127
+ OLLAMA_BASE_URL="http://localhost:11434"
128
+ ```
129
+
130
+ ### MixedBread AI
131
+
132
+ For MxBAI reranking, install with mxbai extras:
133
+
134
+ ```bash
135
+ uv pip install haiku.rag[mxbai]
136
+ ```
137
+
138
+ Then configure:
117
139
 
118
140
  ```bash
119
141
  RERANK_PROVIDER="mxbai"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "haiku.rag"
3
- version = "0.5.1"
3
+ version = "0.5.2"
4
4
  description = "Retrieval Augmented Generation (RAG) with SQLite"
5
5
  authors = [{ name = "Yiorgis Gozadinos", email = "ggozadinos@gmail.com" }]
6
6
  license = { text = "MIT" }
@@ -25,8 +25,7 @@ dependencies = [
25
25
  "docling>=2.15.0",
26
26
  "fastmcp>=2.8.1",
27
27
  "httpx>=0.28.1",
28
- "mxbai-rerank>=0.1.6",
29
- "ollama>=0.5.1",
28
+ "ollama>=0.5.3",
30
29
  "pydantic>=2.11.7",
31
30
  "python-dotenv>=1.1.0",
32
31
  "rich>=14.0.0",
@@ -41,6 +40,7 @@ voyageai = ["voyageai>=0.3.2"]
41
40
  openai = ["openai>=1.0.0"]
42
41
  anthropic = ["anthropic>=0.56.0"]
43
42
  cohere = ["cohere>=5.16.1"]
43
+ mxbai = ["mxbai-rerank>=0.1.6"]
44
44
 
45
45
  [project.scripts]
46
46
  haiku-rag = "haiku.rag.cli:cli"
@@ -32,9 +32,9 @@ class HaikuRAGApp:
32
32
  f"[b]Document with id [cyan]{doc.id}[/cyan] added successfully.[/b]"
33
33
  )
34
34
 
35
- async def add_document_from_source(self, file_path: Path):
35
+ async def add_document_from_source(self, source: str):
36
36
  async with HaikuRAG(db_path=self.db_path) as self.client:
37
- doc = await self.client.create_document_from_source(file_path)
37
+ doc = await self.client.create_document_from_source(source)
38
38
  self._rich_print_document(doc, truncate=True)
39
39
  self.console.print(
40
40
  f"[b]Document with id [cyan]{doc.id}[/cyan] added successfully.[/b]"
@@ -81,7 +81,7 @@ def add_document_text(
81
81
 
82
82
  @cli.command("add-src", help="Add a document from a file path or URL")
83
83
  def add_document_src(
84
- file_path: Path = typer.Argument(
84
+ source: str = typer.Argument(
85
85
  help="The file path or URL of the document to add",
86
86
  ),
87
87
  db: Path = typer.Option(
@@ -91,7 +91,7 @@ def add_document_src(
91
91
  ),
92
92
  ):
93
93
  app = HaikuRAGApp(db_path=db)
94
- asyncio.run(app.add_document_from_source(file_path=file_path))
94
+ asyncio.run(app.add_document_from_source(source=source))
95
95
 
96
96
 
97
97
  @cli.command("get", help="Get and display a document by its ID")
@@ -319,7 +319,7 @@ class HaikuRAG:
319
319
  return await self.document_repository.list_all(limit=limit, offset=offset)
320
320
 
321
321
  async def search(
322
- self, query: str, limit: int = 5, k: int = 60, rerank=Config.RERANK
322
+ self, query: str, limit: int = 5, k: int = 60
323
323
  ) -> list[tuple[Chunk, float]]:
324
324
  """Search for relevant chunks using hybrid search (vector similarity + full-text search) with reranking.
325
325
 
@@ -331,8 +331,10 @@ class HaikuRAG:
331
331
  Returns:
332
332
  List of (chunk, score) tuples ordered by relevance.
333
333
  """
334
+ # Get reranker if available
335
+ reranker = get_reranker()
334
336
 
335
- if not rerank:
337
+ if reranker is None:
336
338
  return await self.chunk_repository.search_chunks_hybrid(query, limit, k)
337
339
 
338
340
  # Get more initial results (3X) for reranking
@@ -340,7 +342,6 @@ class HaikuRAG:
340
342
  query, limit * 3, k
341
343
  )
342
344
  # Apply reranking
343
- reranker = get_reranker()
344
345
  chunks = [chunk for chunk, _ in search_results]
345
346
  reranked_results = await reranker.rerank(query, chunks, top_n=limit)
346
347
 
@@ -19,9 +19,8 @@ class AppConfig(BaseModel):
19
19
  EMBEDDINGS_MODEL: str = "mxbai-embed-large"
20
20
  EMBEDDINGS_VECTOR_DIM: int = 1024
21
21
 
22
- RERANK: bool = True
23
- RERANK_PROVIDER: str = "mxbai"
24
- RERANK_MODEL: str = "mixedbread-ai/mxbai-rerank-base-v2"
22
+ RERANK_PROVIDER: str = "ollama"
23
+ RERANK_MODEL: str = "qwen3"
25
24
 
26
25
  QA_PROVIDER: str = "ollama"
27
26
  QA_MODEL: str = "qwen3"
@@ -0,0 +1,40 @@
1
+ from haiku.rag.config import Config
2
+ from haiku.rag.reranking.base import RerankerBase
3
+
4
+ _reranker: RerankerBase | None = None
5
+
6
+
7
+ def get_reranker() -> RerankerBase | None:
8
+ """
9
+ Factory function to get the appropriate reranker based on the configuration.
10
+ Returns None if if reranking is disabled.
11
+ """
12
+ global _reranker
13
+ if _reranker is not None:
14
+ return _reranker
15
+
16
+ if Config.RERANK_PROVIDER == "mxbai":
17
+ try:
18
+ from haiku.rag.reranking.mxbai import MxBAIReranker
19
+
20
+ _reranker = MxBAIReranker()
21
+ return _reranker
22
+ except ImportError:
23
+ return None
24
+
25
+ if Config.RERANK_PROVIDER == "cohere":
26
+ try:
27
+ from haiku.rag.reranking.cohere import CohereReranker
28
+
29
+ _reranker = CohereReranker()
30
+ return _reranker
31
+ except ImportError:
32
+ return None
33
+
34
+ if Config.RERANK_PROVIDER == "ollama":
35
+ from haiku.rag.reranking.ollama import OllamaReranker
36
+
37
+ _reranker = OllamaReranker()
38
+ return _reranker
39
+
40
+ return None
@@ -0,0 +1,84 @@
1
+ import json
2
+
3
+ from ollama import AsyncClient
4
+ from pydantic import BaseModel
5
+
6
+ from haiku.rag.config import Config
7
+ from haiku.rag.reranking.base import RerankerBase
8
+ from haiku.rag.store.models.chunk import Chunk
9
+
10
+ OLLAMA_OPTIONS = {"temperature": 0.0, "seed": 42, "num_ctx": 16384}
11
+
12
+
13
+ class RerankResult(BaseModel):
14
+ """Individual rerank result with index and relevance score."""
15
+
16
+ index: int
17
+ relevance_score: float
18
+
19
+
20
+ class RerankResponse(BaseModel):
21
+ """Response from the reranking model containing ranked results."""
22
+
23
+ results: list[RerankResult]
24
+
25
+
26
+ class OllamaReranker(RerankerBase):
27
+ def __init__(self, model: str = Config.RERANK_MODEL):
28
+ self._model = model
29
+ self._client = AsyncClient(host=Config.OLLAMA_BASE_URL)
30
+
31
+ async def rerank(
32
+ self, query: str, chunks: list[Chunk], top_n: int = 10
33
+ ) -> list[tuple[Chunk, float]]:
34
+ if not chunks:
35
+ return []
36
+
37
+ documents = []
38
+ for i, chunk in enumerate(chunks):
39
+ documents.append({"index": i, "content": chunk.content})
40
+
41
+ # Create the prompt for reranking
42
+ system_prompt = """You are a document reranking assistant. Given a query and a list of document chunks, you must rank them by relevance to the query.
43
+
44
+ Return your response as a JSON object with a "results" array. Each result should have:
45
+ - "index": the original index of the document (integer)
46
+ - "relevance_score": a score between 0.0 and 1.0 indicating relevance (float, where 1.0 is most relevant)
47
+
48
+ Only return the top documents up to the requested limit, ordered by decreasing relevance score."""
49
+
50
+ documents_text = ""
51
+ for doc in documents:
52
+ documents_text += f"Index {doc['index']}: {doc['content']}\n\n"
53
+
54
+ user_prompt = f"""Query: {query}
55
+
56
+ Documents to rerank:
57
+ {documents_text.strip()}
58
+
59
+ Please rank these documents by relevance to the query and return the top {top_n} results as JSON."""
60
+
61
+ messages = [
62
+ {"role": "system", "content": system_prompt},
63
+ {"role": "user", "content": user_prompt},
64
+ ]
65
+
66
+ try:
67
+ response = await self._client.chat(
68
+ model=self._model,
69
+ messages=messages,
70
+ format=RerankResponse.model_json_schema(),
71
+ options=OLLAMA_OPTIONS,
72
+ )
73
+
74
+ content = response["message"]["content"]
75
+
76
+ parsed_response = RerankResponse.model_validate(json.loads(content))
77
+ return [
78
+ (chunks[result.index], result.relevance_score)
79
+ for result in parsed_response.results[:top_n]
80
+ ]
81
+
82
+ except Exception:
83
+ # Fallback: return chunks in original order with same score
84
+ return [(chunks[i], 1.0) for i in range(min(top_n, len(chunks)))]
@@ -1,7 +1,6 @@
1
1
  import pytest
2
2
 
3
3
  from haiku.rag.reranking.base import RerankerBase
4
- from haiku.rag.reranking.mxbai import MxBAIReranker
5
4
  from haiku.rag.store.models.chunk import Chunk
6
5
 
7
6
  chunks = [
@@ -22,7 +21,7 @@ chunks = [
22
21
  @pytest.mark.asyncio
23
22
  async def test_reranker_base():
24
23
  reranker = RerankerBase()
25
- assert reranker._model == "mixedbread-ai/mxbai-rerank-base-v2"
24
+ assert reranker._model == "qwen3"
26
25
 
27
26
  with pytest.raises(NotImplementedError):
28
27
  await reranker.rerank("query", [])
@@ -30,12 +29,17 @@ async def test_reranker_base():
30
29
 
31
30
  @pytest.mark.asyncio
32
31
  async def test_mxbai_reranker():
33
- reranker = MxBAIReranker()
34
- reranked = await reranker.rerank(
35
- "Who wrote 'To Kill a Mockingbird'?", chunks, top_n=2
36
- )
37
- assert [chunk.document_id for chunk, score in reranked] == [0, 2]
38
- assert all(isinstance(score, float) for chunk, score in reranked)
32
+ try:
33
+ from haiku.rag.reranking.mxbai import MxBAIReranker
34
+
35
+ reranker = MxBAIReranker()
36
+ reranked = await reranker.rerank(
37
+ "Who wrote 'To Kill a Mockingbird'?", chunks, top_n=2
38
+ )
39
+ assert [chunk.document_id for chunk, score in reranked] == [0, 2]
40
+ assert all(isinstance(score, float) for chunk, score in reranked)
41
+ except ImportError:
42
+ pytest.skip("MxBAI package not installed")
39
43
 
40
44
 
41
45
  @pytest.mark.asyncio
@@ -54,3 +58,16 @@ async def test_cohere_reranker():
54
58
 
55
59
  except ImportError:
56
60
  pytest.skip("Cohere package not installed")
61
+
62
+
63
+ @pytest.mark.asyncio
64
+ async def test_ollama_reranker():
65
+ from haiku.rag.reranking.ollama import OllamaReranker
66
+
67
+ reranker = OllamaReranker()
68
+ reranked = await reranker.rerank(
69
+ "Who wrote 'To Kill a Mockingbird'?", chunks, top_n=2
70
+ )
71
+
72
+ assert [chunk.document_id for chunk, score in reranked] == [0, 2]
73
+ assert all(isinstance(score, float) for chunk, score in reranked)
@@ -880,13 +880,12 @@ wheels = [
880
880
 
881
881
  [[package]]
882
882
  name = "haiku-rag"
883
- version = "0.5.1"
883
+ version = "0.5.2"
884
884
  source = { editable = "." }
885
885
  dependencies = [
886
886
  { name = "docling" },
887
887
  { name = "fastmcp" },
888
888
  { name = "httpx" },
889
- { name = "mxbai-rerank" },
890
889
  { name = "ollama" },
891
890
  { name = "pydantic" },
892
891
  { name = "python-dotenv" },
@@ -904,6 +903,9 @@ anthropic = [
904
903
  cohere = [
905
904
  { name = "cohere" },
906
905
  ]
906
+ mxbai = [
907
+ { name = "mxbai-rerank" },
908
+ ]
907
909
  openai = [
908
910
  { name = "openai" },
909
911
  ]
@@ -931,8 +933,8 @@ requires-dist = [
931
933
  { name = "docling", specifier = ">=2.15.0" },
932
934
  { name = "fastmcp", specifier = ">=2.8.1" },
933
935
  { name = "httpx", specifier = ">=0.28.1" },
934
- { name = "mxbai-rerank", specifier = ">=0.1.6" },
935
- { name = "ollama", specifier = ">=0.5.1" },
936
+ { name = "mxbai-rerank", marker = "extra == 'mxbai'", specifier = ">=0.1.6" },
937
+ { name = "ollama", specifier = ">=0.5.3" },
936
938
  { name = "openai", marker = "extra == 'openai'", specifier = ">=1.0.0" },
937
939
  { name = "pydantic", specifier = ">=2.11.7" },
938
940
  { name = "python-dotenv", specifier = ">=1.1.0" },
@@ -943,7 +945,7 @@ requires-dist = [
943
945
  { name = "voyageai", marker = "extra == 'voyageai'", specifier = ">=0.3.2" },
944
946
  { name = "watchfiles", specifier = ">=1.1.0" },
945
947
  ]
946
- provides-extras = ["voyageai", "openai", "anthropic", "cohere"]
948
+ provides-extras = ["voyageai", "openai", "anthropic", "cohere", "mxbai"]
947
949
 
948
950
  [package.metadata.requires-dev]
949
951
  dev = [
@@ -1827,15 +1829,15 @@ wheels = [
1827
1829
 
1828
1830
  [[package]]
1829
1831
  name = "ollama"
1830
- version = "0.5.1"
1832
+ version = "0.5.3"
1831
1833
  source = { registry = "https://pypi.org/simple" }
1832
1834
  dependencies = [
1833
1835
  { name = "httpx" },
1834
1836
  { name = "pydantic" },
1835
1837
  ]
1836
- sdist = { url = "https://files.pythonhosted.org/packages/8d/96/c7fe0d2d1b3053be614822a7b722c7465161b3672ce90df71515137580a0/ollama-0.5.1.tar.gz", hash = "sha256:5a799e4dc4e7af638b11e3ae588ab17623ee019e496caaf4323efbaa8feeff93", size = 41112, upload-time = "2025-05-30T21:32:48.679Z" }
1838
+ sdist = { url = "https://files.pythonhosted.org/packages/91/6d/ae96027416dcc2e98c944c050c492789502d7d7c0b95a740f0bb39268632/ollama-0.5.3.tar.gz", hash = "sha256:40b6dff729df3b24e56d4042fd9d37e231cee8e528677e0d085413a1d6692394", size = 43331, upload-time = "2025-08-07T21:44:10.422Z" }
1837
1839
  wheels = [
1838
- { url = "https://files.pythonhosted.org/packages/d6/76/3f96c8cdbf3955d7a73ee94ce3e0db0755d6de1e0098a70275940d1aff2f/ollama-0.5.1-py3-none-any.whl", hash = "sha256:4c8839f35bc173c7057b1eb2cbe7f498c1a7e134eafc9192824c8aecb3617506", size = 13369, upload-time = "2025-05-30T21:32:47.429Z" },
1840
+ { url = "https://files.pythonhosted.org/packages/be/f6/2091e50b8b6c3e6901f6eab283d5efd66fb71c86ddb1b4d68766c3eeba0f/ollama-0.5.3-py3-none-any.whl", hash = "sha256:a8303b413d99a9043dbf77ebf11ced672396b59bec27e6d5db67c88f01b279d2", size = 13490, upload-time = "2025-08-07T21:44:09.353Z" },
1839
1841
  ]
1840
1842
 
1841
1843
  [[package]]
@@ -1,37 +0,0 @@
1
- from haiku.rag.config import Config
2
- from haiku.rag.reranking.base import RerankerBase
3
-
4
- try:
5
- from haiku.rag.reranking.cohere import CohereReranker
6
- except ImportError:
7
- pass
8
-
9
- _reranker: RerankerBase | None = None
10
-
11
-
12
- def get_reranker() -> RerankerBase:
13
- """
14
- Factory function to get the appropriate reranker based on the configuration.
15
- """
16
- global _reranker
17
- if _reranker is not None:
18
- return _reranker
19
- if Config.RERANK_PROVIDER == "mxbai":
20
- from haiku.rag.reranking.mxbai import MxBAIReranker
21
-
22
- _reranker = MxBAIReranker()
23
- return _reranker
24
-
25
- if Config.RERANK_PROVIDER == "cohere":
26
- try:
27
- from haiku.rag.reranking.cohere import CohereReranker
28
- except ImportError:
29
- raise ImportError(
30
- "Cohere reranker requires the 'cohere' package. "
31
- "Please install haiku.rag with the 'cohere' extra:"
32
- "uv pip install haiku.rag[cohere]"
33
- )
34
- _reranker = CohereReranker()
35
- return _reranker
36
-
37
- raise ValueError(f"Unsupported reranker provider: {Config.RERANK_PROVIDER}")
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