opensolr-haystack 0.2.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: opensolr-haystack
3
- Version: 0.2.3
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 hybrid search, return docs."""
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,6 +321,7 @@ 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
326
  """Build the LLM context from the top hybrid search hits.
313
327
 
@@ -329,7 +343,7 @@ class OpensolrClient:
329
343
  hits: List[Dict[str, Any]] = []
330
344
  if not fq:
331
345
  try:
332
- body = self.embed_and_search(index, query, rows=docs)
346
+ body = self.embed_and_search(index, query, rows=docs, **(tuning or {}))
333
347
  if isinstance(body, dict):
334
348
  hits = body.get("results", {}).get("docs", []) or []
335
349
  except (OpensolrError, httpx.HTTPError):
@@ -357,6 +371,7 @@ class OpensolrClient:
357
371
  rag_docs: Optional[int] = None,
358
372
  rag_words: Optional[int] = None,
359
373
  instruction: Optional[str] = None,
374
+ tuning: Optional[Dict[str, Any]] = None,
360
375
  **params: Any,
361
376
  ) -> str:
362
377
  """Grounded RAG answer: hybrid retrieval over the index feeds the LLM.
@@ -380,7 +395,8 @@ class OpensolrClient:
380
395
  if "context" not in data:
381
396
  try:
382
397
  context = self._rag_context(
383
- 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,
384
400
  )
385
401
  except (OpensolrError, httpx.HTTPError):
386
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
- Returns plain text.
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
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.3"
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" }