opensolr-haystack 0.2.2__tar.gz → 0.2.4__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.
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/PKG-INFO +18 -1
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/README.md +17 -0
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/haystack_integrations/document_stores/opensolr/client.py +41 -7
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/haystack_integrations/document_stores/opensolr/store.py +6 -1
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/opensolr_haystack.egg-info/PKG-INFO +18 -1
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/pyproject.toml +1 -1
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/LICENSE +0 -0
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/haystack_integrations/components/retrievers/opensolr/__init__.py +0 -0
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/haystack_integrations/components/retrievers/opensolr/retriever.py +0 -0
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/haystack_integrations/document_stores/opensolr/__init__.py +0 -0
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/opensolr_haystack.egg-info/SOURCES.txt +0 -0
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/opensolr_haystack.egg-info/dependency_links.txt +0 -0
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/opensolr_haystack.egg-info/requires.txt +0 -0
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/opensolr_haystack.egg-info/top_level.txt +0 -0
- {opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensolr-haystack
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Haystack integration for Opensolr — managed Apache Solr DocumentStore with server-side embeddings and hybrid BM25+kNN retrieval
|
|
5
5
|
Author-email: Opensolr <support@opensolr.com>
|
|
6
6
|
License: MIT
|
|
@@ -136,6 +136,23 @@ answer = store.ai_answer(
|
|
|
136
136
|
)
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
+
|
|
140
|
+
### Search tuning
|
|
141
|
+
|
|
142
|
+
Retrieval (search and RAG grounding) runs through the platform's tuned
|
|
143
|
+
pipeline: global defaults → your index's saved **Search Tuning** (Control
|
|
144
|
+
Panel → Index Settings → Search Tuning: semantic↔lexical balance, field
|
|
145
|
+
weights, minimum match, search mode, vector candidate pool, content quality
|
|
146
|
+
boost) → optional per-call overrides via `tuning`:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
tuning={"search_mode": "keywords_required", "fw_title": 0.2,
|
|
150
|
+
"mm": "strict", "vector_topk": 500, "quality_boost": 0.3}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Defaults match the platform's PHP configuration exactly — customize in the
|
|
154
|
+
Control Panel once, or per call from code.
|
|
155
|
+
|
|
139
156
|
## How it's tested
|
|
140
157
|
|
|
141
158
|
Every release is validated against **live Opensolr infrastructure** — no mocks:
|
|
@@ -118,6 +118,23 @@ answer = store.ai_answer(
|
|
|
118
118
|
)
|
|
119
119
|
```
|
|
120
120
|
|
|
121
|
+
|
|
122
|
+
### Search tuning
|
|
123
|
+
|
|
124
|
+
Retrieval (search and RAG grounding) runs through the platform's tuned
|
|
125
|
+
pipeline: global defaults → your index's saved **Search Tuning** (Control
|
|
126
|
+
Panel → Index Settings → Search Tuning: semantic↔lexical balance, field
|
|
127
|
+
weights, minimum match, search mode, vector candidate pool, content quality
|
|
128
|
+
boost) → optional per-call overrides via `tuning`:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
tuning={"search_mode": "keywords_required", "fw_title": 0.2,
|
|
132
|
+
"mm": "strict", "vector_topk": 500, "quality_boost": 0.3}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Defaults match the platform's PHP configuration exactly — customize in the
|
|
136
|
+
Control Panel once, or per call from code.
|
|
137
|
+
|
|
121
138
|
## How it's tested
|
|
122
139
|
|
|
123
140
|
Every release is validated against **live Opensolr infrastructure** — no mocks:
|
|
@@ -233,7 +233,20 @@ class OpensolrClient:
|
|
|
233
233
|
raise OpensolrError(f"ingest_status: non-JSON response: {resp.text[:200]}") from exc
|
|
234
234
|
|
|
235
235
|
def embed_and_search(self, index: str, query: str, rows: int = 10, **params: Any) -> Dict[str, Any]:
|
|
236
|
-
"""Server-side one-shot: embed the query, run
|
|
236
|
+
"""Server-side one-shot: embed the query, run the platform's tuned
|
|
237
|
+
hybrid search, return ranked docs.
|
|
238
|
+
|
|
239
|
+
Retrieval uses the same pipeline as the hosted search UI: global
|
|
240
|
+
defaults, overridden by the index's saved Search Tuning (Control
|
|
241
|
+
Panel → Index Settings → Search Tuning), overridden by any of these
|
|
242
|
+
per-call knobs passed as extra params: ``fw_title``,
|
|
243
|
+
``fw_description``, ``fw_uri``, ``fw_text``, ``fw_text_t``,
|
|
244
|
+
``lexical_weight``, ``vector_weight``, ``vector_topk``,
|
|
245
|
+
``search_mode`` (union / keywords_required / meaning_required /
|
|
246
|
+
intersection), ``quality_boost``, ``min_score``,
|
|
247
|
+
``freshness_boost``, ``lexical_norm_k``, ``mm`` (flexible /
|
|
248
|
+
balanced / strict or raw Solr mm syntax).
|
|
249
|
+
"""
|
|
237
250
|
body = self.ai(
|
|
238
251
|
"embed_and_search",
|
|
239
252
|
index_name=index,
|
|
@@ -308,8 +321,17 @@ class OpensolrClient:
|
|
|
308
321
|
fq: Optional[str] = None,
|
|
309
322
|
docs: Optional[int] = None,
|
|
310
323
|
words: Optional[int] = None,
|
|
324
|
+
tuning: Optional[Dict[str, Any]] = None,
|
|
311
325
|
) -> str:
|
|
312
|
-
"""Build the LLM context from the top hybrid search hits.
|
|
326
|
+
"""Build the LLM context from the top hybrid search hits.
|
|
327
|
+
|
|
328
|
+
Retrieval runs through the server-side ``embed_and_search`` pipeline —
|
|
329
|
+
the platform's own tuned hybrid ranking (field weights, minimum-match,
|
|
330
|
+
quality boosts), the same machinery behind the hosted search UI, so it
|
|
331
|
+
improves automatically with the platform. When a custom ``fq`` is
|
|
332
|
+
given (which that endpoint doesn't accept) — or if it fails —
|
|
333
|
+
retrieval falls back to the client-side ``{!hybrid}`` query.
|
|
334
|
+
"""
|
|
313
335
|
|
|
314
336
|
def _flat(v: Any) -> str:
|
|
315
337
|
if isinstance(v, list):
|
|
@@ -318,11 +340,21 @@ class OpensolrClient:
|
|
|
318
340
|
|
|
319
341
|
docs = docs or self.RAG_DOCS
|
|
320
342
|
words = words or self.RAG_WORDS
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
343
|
+
hits: List[Dict[str, Any]] = []
|
|
344
|
+
if not fq:
|
|
345
|
+
try:
|
|
346
|
+
body = self.embed_and_search(index, query, rows=docs, **(tuning or {}))
|
|
347
|
+
if isinstance(body, dict):
|
|
348
|
+
hits = body.get("results", {}).get("docs", []) or []
|
|
349
|
+
except (OpensolrError, httpx.HTTPError):
|
|
350
|
+
hits = []
|
|
351
|
+
if not hits:
|
|
352
|
+
body = self.hybrid_search(
|
|
353
|
+
index, query, rows=docs, fl="title,description,text", fq=fq
|
|
354
|
+
)
|
|
355
|
+
hits = body.get("response", {}).get("docs", [])
|
|
324
356
|
parts: List[str] = []
|
|
325
|
-
for doc in
|
|
357
|
+
for doc in hits[:docs]:
|
|
326
358
|
text_words = _flat(doc.get("text")).split()[:words]
|
|
327
359
|
parts.append(
|
|
328
360
|
_flat(doc.get("title")) + " - "
|
|
@@ -339,6 +371,7 @@ class OpensolrClient:
|
|
|
339
371
|
rag_docs: Optional[int] = None,
|
|
340
372
|
rag_words: Optional[int] = None,
|
|
341
373
|
instruction: Optional[str] = None,
|
|
374
|
+
tuning: Optional[Dict[str, Any]] = None,
|
|
342
375
|
**params: Any,
|
|
343
376
|
) -> str:
|
|
344
377
|
"""Grounded RAG answer: hybrid retrieval over the index feeds the LLM.
|
|
@@ -362,7 +395,8 @@ class OpensolrClient:
|
|
|
362
395
|
if "context" not in data:
|
|
363
396
|
try:
|
|
364
397
|
context = self._rag_context(
|
|
365
|
-
index, query, fq=filter_query, docs=rag_docs, words=rag_words
|
|
398
|
+
index, query, fq=filter_query, docs=rag_docs, words=rag_words,
|
|
399
|
+
tuning=tuning,
|
|
366
400
|
)
|
|
367
401
|
except (OpensolrError, httpx.HTTPError):
|
|
368
402
|
context = ""
|
|
@@ -255,6 +255,7 @@ class OpensolrDocumentStore:
|
|
|
255
255
|
rag_docs: int = 3,
|
|
256
256
|
rag_words: int = 1500,
|
|
257
257
|
instruction: Optional[str] = None,
|
|
258
|
+
tuning: Optional[Dict[str, Any]] = None,
|
|
258
259
|
**kwargs: Any,
|
|
259
260
|
) -> str:
|
|
260
261
|
"""Grounded RAG answer generated only from this index's content.
|
|
@@ -264,13 +265,17 @@ class OpensolrDocumentStore:
|
|
|
264
265
|
title/description/text become the LLM context — the same pipeline as
|
|
265
266
|
Opensolr's hosted search UI. Pass ``instruction`` to fully control
|
|
266
267
|
the prompt (e.g. "Answer in German, cite the sources you used").
|
|
267
|
-
|
|
268
|
+
Retrieval uses the platform's tuned pipeline: your index's saved
|
|
269
|
+
Search Tuning (Control Panel) applies automatically; ``tuning``
|
|
270
|
+
overrides any knob per call (fw_title, lexical_weight, search_mode,
|
|
271
|
+
mm, vector_topk, quality_boost, ...). Returns plain text.
|
|
268
272
|
"""
|
|
269
273
|
fqs = _filters_to_fq(filters)
|
|
270
274
|
fq = " AND ".join(f"({f})" for f in fqs) if fqs else None
|
|
271
275
|
return self.client.ai_summary(
|
|
272
276
|
self.index, query, filter_query=fq,
|
|
273
277
|
rag_docs=rag_docs, rag_words=rag_words, instruction=instruction,
|
|
278
|
+
tuning=tuning,
|
|
274
279
|
**kwargs,
|
|
275
280
|
)
|
|
276
281
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opensolr-haystack
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Haystack integration for Opensolr — managed Apache Solr DocumentStore with server-side embeddings and hybrid BM25+kNN retrieval
|
|
5
5
|
Author-email: Opensolr <support@opensolr.com>
|
|
6
6
|
License: MIT
|
|
@@ -136,6 +136,23 @@ answer = store.ai_answer(
|
|
|
136
136
|
)
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
+
|
|
140
|
+
### Search tuning
|
|
141
|
+
|
|
142
|
+
Retrieval (search and RAG grounding) runs through the platform's tuned
|
|
143
|
+
pipeline: global defaults → your index's saved **Search Tuning** (Control
|
|
144
|
+
Panel → Index Settings → Search Tuning: semantic↔lexical balance, field
|
|
145
|
+
weights, minimum match, search mode, vector candidate pool, content quality
|
|
146
|
+
boost) → optional per-call overrides via `tuning`:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
tuning={"search_mode": "keywords_required", "fw_title": 0.2,
|
|
150
|
+
"mm": "strict", "vector_topk": 500, "quality_boost": 0.3}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Defaults match the platform's PHP configuration exactly — customize in the
|
|
154
|
+
Control Panel once, or per call from code.
|
|
155
|
+
|
|
139
156
|
## How it's tested
|
|
140
157
|
|
|
141
158
|
Every release is validated against **live Opensolr infrastructure** — no mocks:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "opensolr-haystack"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.4"
|
|
8
8
|
description = "Haystack integration for Opensolr — managed Apache Solr DocumentStore with server-side embeddings and hybrid BM25+kNN retrieval"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/opensolr_haystack.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{opensolr_haystack-0.2.2 → opensolr_haystack-0.2.4}/opensolr_haystack.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|