nucliadb 6.4.0.post4204__py3-none-any.whl → 6.4.0.post4210__py3-none-any.whl
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.
- nucliadb/common/external_index_providers/base.py +7 -4
- nucliadb/search/search/chat/ask.py +43 -32
- nucliadb/search/search/find_merge.py +8 -2
- nucliadb/search/search/rank_fusion.py +136 -58
- {nucliadb-6.4.0.post4204.dist-info → nucliadb-6.4.0.post4210.dist-info}/METADATA +6 -6
- {nucliadb-6.4.0.post4204.dist-info → nucliadb-6.4.0.post4210.dist-info}/RECORD +9 -9
- {nucliadb-6.4.0.post4204.dist-info → nucliadb-6.4.0.post4210.dist-info}/WHEEL +0 -0
- {nucliadb-6.4.0.post4204.dist-info → nucliadb-6.4.0.post4210.dist-info}/entry_points.txt +0 -0
- {nucliadb-6.4.0.post4204.dist-info → nucliadb-6.4.0.post4210.dist-info}/top_level.txt +0 -0
@@ -55,16 +55,19 @@ class VectorsetExternalIndex:
|
|
55
55
|
similarity: VectorSimilarity.ValueType
|
56
56
|
|
57
57
|
|
58
|
-
class
|
58
|
+
class ScoredTextBlock(BaseModel):
|
59
|
+
paragraph_id: ParagraphId
|
60
|
+
score: float
|
61
|
+
score_type: SCORE_TYPE
|
62
|
+
|
63
|
+
|
64
|
+
class TextBlockMatch(ScoredTextBlock):
|
59
65
|
"""
|
60
66
|
Model a text block/paragraph retrieved from an external index with all the information
|
61
67
|
needed in order to later hydrate retrieval results.
|
62
68
|
"""
|
63
69
|
|
64
|
-
paragraph_id: ParagraphId
|
65
70
|
position: TextPosition
|
66
|
-
score: float
|
67
|
-
score_type: SCORE_TYPE
|
68
71
|
order: int
|
69
72
|
page_with_visual: bool = False
|
70
73
|
fuzzy_search: bool
|
@@ -33,6 +33,8 @@ from nuclia_models.predict.generative_responses import (
|
|
33
33
|
from pydantic_core import ValidationError
|
34
34
|
|
35
35
|
from nucliadb.common.datamanagers.exceptions import KnowledgeBoxNotFound
|
36
|
+
from nucliadb.common.external_index_providers.base import ScoredTextBlock
|
37
|
+
from nucliadb.common.ids import ParagraphId
|
36
38
|
from nucliadb.models.responses import HTTPClientError
|
37
39
|
from nucliadb.search import logger, predict
|
38
40
|
from nucliadb.search.predict import (
|
@@ -63,6 +65,7 @@ from nucliadb.search.search.graph_strategy import get_graph_results
|
|
63
65
|
from nucliadb.search.search.metrics import RAGMetrics
|
64
66
|
from nucliadb.search.search.query_parser.fetcher import Fetcher
|
65
67
|
from nucliadb.search.search.query_parser.parsers.ask import fetcher_for_ask, parse_ask
|
68
|
+
from nucliadb.search.search.rank_fusion import WeightedCombSum
|
66
69
|
from nucliadb.search.search.rerankers import (
|
67
70
|
get_reranker,
|
68
71
|
)
|
@@ -865,6 +868,10 @@ async def retrieval_in_resource(
|
|
865
868
|
)
|
866
869
|
|
867
870
|
|
871
|
+
class _FindParagraph(ScoredTextBlock):
|
872
|
+
original: FindParagraph
|
873
|
+
|
874
|
+
|
868
875
|
def compute_best_matches(
|
869
876
|
main_results: KnowledgeboxFindResults,
|
870
877
|
prequeries_results: Optional[list[PreQueryResult]] = None,
|
@@ -882,42 +889,46 @@ def compute_best_matches(
|
|
882
889
|
`main_query_weight` is the weight given to the paragraphs matching the main query when calculating the final score.
|
883
890
|
"""
|
884
891
|
|
885
|
-
def
|
892
|
+
def extract_paragraphs(results: KnowledgeboxFindResults) -> list[_FindParagraph]:
|
893
|
+
paragraphs = []
|
886
894
|
for resource in results.resources.values():
|
887
895
|
for field in resource.fields.values():
|
888
896
|
for paragraph in field.paragraphs.values():
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
)
|
899
|
-
paragraph_id_to_match[paragraph.id] = rmatch
|
900
|
-
|
901
|
-
for prequery, prequery_results in prequeries_results or []:
|
902
|
-
for paragraph in iter_paragraphs(prequery_results):
|
903
|
-
normalized_weight = prequery.weight / total_weights
|
904
|
-
weighted_score = paragraph.score * normalized_weight
|
905
|
-
if paragraph.id in paragraph_id_to_match:
|
906
|
-
rmatch = paragraph_id_to_match[paragraph.id]
|
907
|
-
# If a paragraph is matched in various prequeries, the final score is the
|
908
|
-
# sum of the weighted scores
|
909
|
-
rmatch.weighted_score += weighted_score
|
910
|
-
else:
|
911
|
-
paragraph_id_to_match[paragraph.id] = RetrievalMatch(
|
912
|
-
paragraph=paragraph,
|
913
|
-
weighted_score=weighted_score,
|
914
|
-
)
|
897
|
+
paragraphs.append(
|
898
|
+
_FindParagraph(
|
899
|
+
paragraph_id=ParagraphId.from_string(paragraph.id),
|
900
|
+
score=paragraph.score,
|
901
|
+
score_type=paragraph.score_type,
|
902
|
+
original=paragraph,
|
903
|
+
)
|
904
|
+
)
|
905
|
+
return paragraphs
|
915
906
|
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
907
|
+
weights = {
|
908
|
+
"main": main_query_weight,
|
909
|
+
}
|
910
|
+
total_weight = main_query_weight
|
911
|
+
find_results = {
|
912
|
+
"main": extract_paragraphs(main_results),
|
913
|
+
}
|
914
|
+
for i, (prequery, prequery_results) in enumerate(prequeries_results or []):
|
915
|
+
weights[f"prequery-{i}"] = prequery.weight
|
916
|
+
total_weight += prequery.weight
|
917
|
+
find_results[f"prequery-{i}"] = extract_paragraphs(prequery_results)
|
918
|
+
|
919
|
+
normalized_weights = {key: value / total_weight for key, value in weights.items()}
|
920
|
+
|
921
|
+
# window does nothing here
|
922
|
+
rank_fusion = WeightedCombSum(window=0, weights=normalized_weights)
|
923
|
+
|
924
|
+
merged = []
|
925
|
+
for item in rank_fusion.fuse(find_results):
|
926
|
+
match = RetrievalMatch(
|
927
|
+
paragraph=item.original,
|
928
|
+
weighted_score=item.score,
|
929
|
+
)
|
930
|
+
merged.append(match)
|
931
|
+
return merged
|
921
932
|
|
922
933
|
|
923
934
|
def calculate_prequeries_for_json_schema(
|
@@ -42,7 +42,7 @@ from nucliadb.search.search.hydrator import (
|
|
42
42
|
)
|
43
43
|
from nucliadb.search.search.merge import merge_relations_results
|
44
44
|
from nucliadb.search.search.query_parser.models import UnitRetrieval
|
45
|
-
from nucliadb.search.search.rank_fusion import RankFusionAlgorithm
|
45
|
+
from nucliadb.search.search.rank_fusion import IndexSource, RankFusionAlgorithm
|
46
46
|
from nucliadb.search.search.rerankers import (
|
47
47
|
RerankableItem,
|
48
48
|
Reranker,
|
@@ -108,7 +108,13 @@ async def build_find_response(
|
|
108
108
|
)
|
109
109
|
graph_results = graph_results_to_text_block_matches(search_response.graph)
|
110
110
|
|
111
|
-
merged_text_blocks = rank_fusion_algorithm.fuse(
|
111
|
+
merged_text_blocks = rank_fusion_algorithm.fuse(
|
112
|
+
{
|
113
|
+
IndexSource.KEYWORD: keyword_results,
|
114
|
+
IndexSource.SEMANTIC: semantic_results,
|
115
|
+
IndexSource.GRAPH: graph_results,
|
116
|
+
}
|
117
|
+
)
|
112
118
|
|
113
119
|
# cut
|
114
120
|
# we assume pagination + predict reranker is forbidden and has been already
|
@@ -19,8 +19,10 @@
|
|
19
19
|
#
|
20
20
|
import logging
|
21
21
|
from abc import ABC, abstractmethod
|
22
|
+
from enum import Enum, auto
|
23
|
+
from typing import Optional, TypeVar
|
22
24
|
|
23
|
-
from nucliadb.common.external_index_providers.base import
|
25
|
+
from nucliadb.common.external_index_providers.base import ScoredTextBlock
|
24
26
|
from nucliadb.common.ids import ParagraphId
|
25
27
|
from nucliadb.search.search.query_parser import models as parser_models
|
26
28
|
from nucliadb_models.search import SCORE_TYPE
|
@@ -45,6 +47,14 @@ rank_fusion_observer = Observer(
|
|
45
47
|
],
|
46
48
|
)
|
47
49
|
|
50
|
+
ScoredItem = TypeVar("ScoredItem", bound=ScoredTextBlock)
|
51
|
+
|
52
|
+
|
53
|
+
class IndexSource(str, Enum):
|
54
|
+
KEYWORD = auto()
|
55
|
+
SEMANTIC = auto()
|
56
|
+
GRAPH = auto()
|
57
|
+
|
48
58
|
|
49
59
|
class RankFusionAlgorithm(ABC):
|
50
60
|
def __init__(self, window: int):
|
@@ -60,46 +70,44 @@ class RankFusionAlgorithm(ABC):
|
|
60
70
|
"""
|
61
71
|
return self._window
|
62
72
|
|
63
|
-
def fuse(
|
64
|
-
|
65
|
-
keyword: list[TextBlockMatch],
|
66
|
-
semantic: list[TextBlockMatch],
|
67
|
-
graph: list[TextBlockMatch],
|
68
|
-
) -> list[TextBlockMatch]:
|
69
|
-
"""Fuse keyword and semantic results and return a list with the merged
|
73
|
+
def fuse(self, sources: dict[str, list[ScoredItem]]) -> list[ScoredItem]:
|
74
|
+
"""Fuse elements from multiple sources and return a list of merged
|
70
75
|
results.
|
71
76
|
|
72
|
-
If only one
|
77
|
+
If only one source is provided, rank fusion will be skipped.
|
73
78
|
|
74
79
|
"""
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
retrievals_with_results = [x for x in (keyword, semantic, graph) if len(x) > 0]
|
81
|
-
if len(retrievals_with_results) == 1:
|
82
|
-
return retrievals_with_results[0]
|
80
|
+
sources_with_results = [x for x in sources.values() if len(x) > 0]
|
81
|
+
if len(sources_with_results) == 1:
|
82
|
+
# skip rank fusion, we only have a source
|
83
|
+
merged = sources_with_results[0]
|
83
84
|
else:
|
84
|
-
merged = self._fuse(
|
85
|
+
merged = self._fuse(sources)
|
86
|
+
|
87
|
+
# sort and return the unordered results from the implementation
|
88
|
+
merged.sort(key=lambda r: r.score, reverse=True)
|
85
89
|
return merged
|
86
90
|
|
87
91
|
@abstractmethod
|
88
|
-
def _fuse(
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
by
|
92
|
+
def _fuse(self, sources: dict[str, list[ScoredItem]]) -> list[ScoredItem]:
|
93
|
+
"""Rank fusion implementation.
|
94
|
+
|
95
|
+
Each concrete subclass must provide an implementation that merges
|
96
|
+
`sources`, a group of unordered matches, into a list of unordered
|
97
|
+
results with the new rank fusion score.
|
98
|
+
|
99
|
+
Results can be deduplicated or changed by the rank fusion algorithm.
|
100
|
+
|
101
|
+
"""
|
96
102
|
...
|
97
103
|
|
98
104
|
|
99
105
|
class ReciprocalRankFusion(RankFusionAlgorithm):
|
100
106
|
"""Rank-based rank fusion algorithm. Discounts the weight of documents
|
101
|
-
occurring deep in retrieved lists using a reciprocal distribution.
|
102
|
-
|
107
|
+
occurring deep in retrieved lists using a reciprocal distribution.
|
108
|
+
|
109
|
+
This implementation can be further parametrized with a weight (boost) per
|
110
|
+
retriever that will be applied to all documents ranked by it.
|
103
111
|
|
104
112
|
RRF = Σ(r ∈ R) (1 / (k + r(d)) · w(r))
|
105
113
|
|
@@ -119,9 +127,8 @@ class ReciprocalRankFusion(RankFusionAlgorithm):
|
|
119
127
|
k: float = 60.0,
|
120
128
|
*,
|
121
129
|
window: int,
|
122
|
-
|
123
|
-
|
124
|
-
graph_weight: float = 1.0,
|
130
|
+
weights: Optional[dict[str, float]] = None,
|
131
|
+
default_weight: float = 1.0,
|
125
132
|
):
|
126
133
|
super().__init__(window)
|
127
134
|
# Constant used in RRF, studies agree on 60 as a good default value
|
@@ -129,49 +136,118 @@ class ReciprocalRankFusion(RankFusionAlgorithm):
|
|
129
136
|
# difference among the best results and a smaller score difference among
|
130
137
|
# bad results
|
131
138
|
self._k = k
|
132
|
-
self.
|
133
|
-
self.
|
134
|
-
self._graph_boost = graph_weight
|
139
|
+
self._weights = weights or {}
|
140
|
+
self._default_weight = default_weight
|
135
141
|
|
136
142
|
@rank_fusion_observer.wrap({"type": "reciprocal_rank_fusion"})
|
137
143
|
def _fuse(
|
138
144
|
self,
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
145
|
+
sources: dict[str, list[ScoredItem]],
|
146
|
+
) -> list[ScoredItem]:
|
147
|
+
# accumulated scores per paragraph
|
148
|
+
scores: dict[ParagraphId, tuple[float, SCORE_TYPE]] = {}
|
149
|
+
# pointers from paragraph to the original source
|
150
|
+
match_positions: dict[ParagraphId, list[tuple[int, int]]] = {}
|
151
|
+
|
152
|
+
# sort results by it's score before fusing them, as we need the rank
|
153
|
+
sources = {
|
154
|
+
retriever: sorted(values, key=lambda r: r.score, reverse=True)
|
155
|
+
for retriever, values in sources.items()
|
156
|
+
}
|
157
|
+
rankings = [
|
158
|
+
(values, self._weights.get(source, self._default_weight))
|
159
|
+
for source, values in sources.items()
|
160
|
+
]
|
161
|
+
for i, (ranking, weight) in enumerate(rankings):
|
162
|
+
for rank, item in enumerate(ranking):
|
163
|
+
id = item.paragraph_id
|
164
|
+
score, score_type = scores.setdefault(id, (0, item.score_type))
|
165
|
+
score += 1 / (self._k + rank) * weight
|
166
|
+
if {score_type, item.score_type} == {SCORE_TYPE.BM25, SCORE_TYPE.VECTOR}:
|
167
|
+
score_type = SCORE_TYPE.BOTH
|
168
|
+
scores[id] = (score, score_type)
|
169
|
+
|
170
|
+
position = (i, rank)
|
171
|
+
match_positions.setdefault(item.paragraph_id, []).append(position)
|
172
|
+
|
173
|
+
merged = []
|
174
|
+
for paragraph_id, positions in match_positions.items():
|
175
|
+
# we are getting only one position, effectively deduplicating
|
176
|
+
# multiple matches for the same text block
|
177
|
+
i, j = match_positions[paragraph_id][0]
|
178
|
+
score, score_type = scores[paragraph_id]
|
179
|
+
item = rankings[i][0][j]
|
180
|
+
item.score = score
|
181
|
+
item.score_type = score_type
|
182
|
+
merged.append(item)
|
183
|
+
|
184
|
+
return merged
|
185
|
+
|
186
|
+
|
187
|
+
class WeightedCombSum(RankFusionAlgorithm):
|
188
|
+
"""Score-based rank fusion algorithm. Multiply each score by a list-specific
|
189
|
+
weight (boost). Then adds the retrieval score of documents contained in more
|
190
|
+
than one list and sort by score.
|
191
|
+
|
192
|
+
wCombSUM = Σ(r ∈ R) (w(r) · S(r, d))
|
193
|
+
|
194
|
+
where:
|
195
|
+
- d is a document
|
196
|
+
- R is the set of retrievers
|
197
|
+
- w(r) weight (boost) for retriever r
|
198
|
+
- S(r, d) is the score of document d given by retriever r
|
199
|
+
|
200
|
+
wCombSUM boosts matches from multiple retrievers and deduplicate them. As a
|
201
|
+
score ranking algorithm, comparison of different scores may lead to bad
|
202
|
+
results.
|
203
|
+
|
204
|
+
"""
|
205
|
+
|
206
|
+
def __init__(
|
207
|
+
self,
|
208
|
+
*,
|
209
|
+
window: int,
|
210
|
+
weights: Optional[dict[str, float]] = None,
|
211
|
+
default_weight: float = 1.0,
|
212
|
+
):
|
213
|
+
super().__init__(window)
|
214
|
+
self._weights = weights or {}
|
215
|
+
self._default_weight = default_weight
|
216
|
+
|
217
|
+
@rank_fusion_observer.wrap({"type": "weighted_comb_sum"})
|
218
|
+
def _fuse(self, sources: dict[str, list[ScoredItem]]) -> list[ScoredItem]:
|
219
|
+
# accumulated scores per paragraph
|
143
220
|
scores: dict[ParagraphId, tuple[float, SCORE_TYPE]] = {}
|
221
|
+
# pointers from paragraph to the original source
|
144
222
|
match_positions: dict[ParagraphId, list[tuple[int, int]]] = {}
|
145
223
|
|
146
224
|
rankings = [
|
147
|
-
(
|
148
|
-
|
149
|
-
(graph, self._graph_boost),
|
225
|
+
(values, self._weights.get(source, self._default_weight))
|
226
|
+
for source, values in sources.items()
|
150
227
|
]
|
151
|
-
for
|
152
|
-
for
|
153
|
-
id =
|
154
|
-
score, score_type = scores.setdefault(id, (0,
|
155
|
-
score +=
|
156
|
-
if {score_type,
|
228
|
+
for i, (ranking, weight) in enumerate(rankings):
|
229
|
+
for j, item in enumerate(ranking):
|
230
|
+
id = item.paragraph_id
|
231
|
+
score, score_type = scores.setdefault(id, (0, item.score_type))
|
232
|
+
score += item.score * weight
|
233
|
+
if {score_type, item.score_type} == {SCORE_TYPE.BM25, SCORE_TYPE.VECTOR}:
|
157
234
|
score_type = SCORE_TYPE.BOTH
|
158
235
|
scores[id] = (score, score_type)
|
159
236
|
|
160
|
-
position = (
|
161
|
-
match_positions.setdefault(
|
237
|
+
position = (i, j)
|
238
|
+
match_positions.setdefault(item.paragraph_id, []).append(position)
|
162
239
|
|
163
240
|
merged = []
|
164
241
|
for paragraph_id, positions in match_positions.items():
|
165
242
|
# we are getting only one position, effectively deduplicating
|
166
243
|
# multiple matches for the same text block
|
167
|
-
|
244
|
+
i, j = match_positions[paragraph_id][0]
|
168
245
|
score, score_type = scores[paragraph_id]
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
merged.append(
|
246
|
+
item = rankings[i][0][j]
|
247
|
+
item.score = score
|
248
|
+
item.score_type = score_type
|
249
|
+
merged.append(item)
|
173
250
|
|
174
|
-
merged.sort(key=lambda x: x.score, reverse=True)
|
175
251
|
return merged
|
176
252
|
|
177
253
|
|
@@ -184,9 +260,11 @@ def get_rank_fusion(rank_fusion: parser_models.RankFusion) -> RankFusionAlgorith
|
|
184
260
|
algorithm = ReciprocalRankFusion(
|
185
261
|
k=rank_fusion.k,
|
186
262
|
window=window,
|
187
|
-
|
188
|
-
|
189
|
-
|
263
|
+
weights={
|
264
|
+
IndexSource.KEYWORD: rank_fusion.boosting.keyword,
|
265
|
+
IndexSource.SEMANTIC: rank_fusion.boosting.semantic,
|
266
|
+
IndexSource.GRAPH: rank_fusion.boosting.graph,
|
267
|
+
},
|
190
268
|
)
|
191
269
|
|
192
270
|
else:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: nucliadb
|
3
|
-
Version: 6.4.0.
|
3
|
+
Version: 6.4.0.post4210
|
4
4
|
Summary: NucliaDB
|
5
5
|
Author-email: Nuclia <nucliadb@nuclia.com>
|
6
6
|
License: AGPL
|
@@ -20,11 +20,11 @@ Classifier: Programming Language :: Python :: 3.12
|
|
20
20
|
Classifier: Programming Language :: Python :: 3 :: Only
|
21
21
|
Requires-Python: <4,>=3.9
|
22
22
|
Description-Content-Type: text/markdown
|
23
|
-
Requires-Dist: nucliadb-telemetry[all]>=6.4.0.
|
24
|
-
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.4.0.
|
25
|
-
Requires-Dist: nucliadb-protos>=6.4.0.
|
26
|
-
Requires-Dist: nucliadb-models>=6.4.0.
|
27
|
-
Requires-Dist: nidx-protos>=6.4.0.
|
23
|
+
Requires-Dist: nucliadb-telemetry[all]>=6.4.0.post4210
|
24
|
+
Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.4.0.post4210
|
25
|
+
Requires-Dist: nucliadb-protos>=6.4.0.post4210
|
26
|
+
Requires-Dist: nucliadb-models>=6.4.0.post4210
|
27
|
+
Requires-Dist: nidx-protos>=6.4.0.post4210
|
28
28
|
Requires-Dist: nucliadb-admin-assets>=1.0.0.post1224
|
29
29
|
Requires-Dist: nuclia-models>=0.24.2
|
30
30
|
Requires-Dist: uvicorn[standard]
|
@@ -93,7 +93,7 @@ nucliadb/common/datamanagers/synonyms.py,sha256=zk3GEH38KF5vV_VcuL6DCg-2JwgXJfQl
|
|
93
93
|
nucliadb/common/datamanagers/utils.py,sha256=McHlXvE4P3x-bBY3pr0n8djbTDQvI1G5WusJrnRdhLA,1827
|
94
94
|
nucliadb/common/datamanagers/vectorsets.py,sha256=ciYb5uD435Zo8ZbqgPUAszFW9Svp_-R2hY2FEhQ411Y,4304
|
95
95
|
nucliadb/common/external_index_providers/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
96
|
-
nucliadb/common/external_index_providers/base.py,sha256=
|
96
|
+
nucliadb/common/external_index_providers/base.py,sha256=BL3DuYbnp-KCmGUiN-FGRtgjWj3SmtgMsGdjGq_7cX4,8905
|
97
97
|
nucliadb/common/external_index_providers/exceptions.py,sha256=nDhhOIkb66hjCrBk4Spvl2vN1SuW5gbwrMCDmrdjHHE,1209
|
98
98
|
nucliadb/common/external_index_providers/manager.py,sha256=aFSrrKKYG1ydpTSyq4zYD0LOxFS7P-CO6rcKC0hiF4I,4267
|
99
99
|
nucliadb/common/external_index_providers/pinecone.py,sha256=sCvMgmXrLebnFLkpLnimDGrm4lE9ydb_ywotOMUSMrI,38124
|
@@ -239,7 +239,7 @@ nucliadb/search/search/exceptions.py,sha256=klGLgAGGrXcSGix_W6418ZBMqDchAIGjN77o
|
|
239
239
|
nucliadb/search/search/fetch.py,sha256=eiljOKim-4OOEZn-3fyVZSYxztCH156BXYdqlIwVdN4,6181
|
240
240
|
nucliadb/search/search/filters.py,sha256=1MkHlJjAQqoRCj7e5cEzK2HvBxGLE17I_omsjiklbtw,6476
|
241
241
|
nucliadb/search/search/find.py,sha256=WTc_0HdbaU0Mwkmlf9s4pCmTuU0hz1jetBjIpNLXEEM,7982
|
242
|
-
nucliadb/search/search/find_merge.py,sha256=
|
242
|
+
nucliadb/search/search/find_merge.py,sha256=c-7IlfjfdmWAvQOyM7IO3bKS1EQpnR4oi6pN6mwrQKw,19815
|
243
243
|
nucliadb/search/search/graph_merge.py,sha256=y5V7X-BhjHsKDXE69tzQLIIKGm4XuaFrZXw0odcHVNM,3402
|
244
244
|
nucliadb/search/search/graph_strategy.py,sha256=JsV-i9PGhekCAzmGpqeueQIitJb7fWCihIwUf76Q3pU,32912
|
245
245
|
nucliadb/search/search/hydrator.py,sha256=-R37gCrGxkyaiHQalnTWHNG_FCx11Zucd7qA1vQCxuw,6985
|
@@ -250,13 +250,13 @@ nucliadb/search/search/paragraphs.py,sha256=pNAEiYqJGGUVcEf7xf-PFMVqz0PX4Qb-WNG-
|
|
250
250
|
nucliadb/search/search/pgcatalog.py,sha256=s_J98fsX_RuFXwpejpkGqG-tD9ELuzz4YQ6U3ew5h2g,9313
|
251
251
|
nucliadb/search/search/predict_proxy.py,sha256=IFI3v_ODz2_UU1XZnyaD391fE7-2C0npSmj_HmDvzS4,3123
|
252
252
|
nucliadb/search/search/query.py,sha256=-gvKsyGmKYpsoEVzKkq3HJUMcs_3LD3TYUueOcJsTec,11511
|
253
|
-
nucliadb/search/search/rank_fusion.py,sha256=
|
253
|
+
nucliadb/search/search/rank_fusion.py,sha256=xZtXhbmKb_56gs73u6KkFm2efvTATOSMmpOV2wrAIqE,9613
|
254
254
|
nucliadb/search/search/rerankers.py,sha256=PvhExUb8zZYghiFHRgGotw6h6bU--Rft09wE8arvtAw,7424
|
255
255
|
nucliadb/search/search/shards.py,sha256=mc5DK-MoCv9AFhlXlOFHbPvetcyNDzTFOJ5rimK8PC8,2636
|
256
256
|
nucliadb/search/search/summarize.py,sha256=ksmYPubEQvAQgfPdZHfzB_rR19B2ci4IYZ6jLdHxZo8,4996
|
257
257
|
nucliadb/search/search/utils.py,sha256=ajRIXfdTF67dBVahQCXW-rSv6gJpUMPt3QhJrWqArTQ,2175
|
258
258
|
nucliadb/search/search/chat/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
|
259
|
-
nucliadb/search/search/chat/ask.py,sha256=
|
259
|
+
nucliadb/search/search/chat/ask.py,sha256=jYOGh2rySV4aFx_D2KlNVbPXHBsbkcy0Ve-eBS7CSYc,37611
|
260
260
|
nucliadb/search/search/chat/exceptions.py,sha256=Siy4GXW2L7oPhIR86H3WHBhE9lkV4A4YaAszuGGUf54,1356
|
261
261
|
nucliadb/search/search/chat/images.py,sha256=PA8VWxT5_HUGfW1ULhKTK46UBsVyINtWWqEM1ulzX1E,3095
|
262
262
|
nucliadb/search/search/chat/prompt.py,sha256=Jnja-Ss7skgnnDY8BymVfdeYsFPnIQFL8tEvcRXTKUE,47356
|
@@ -369,8 +369,8 @@ nucliadb/writer/tus/local.py,sha256=7jYa_w9b-N90jWgN2sQKkNcomqn6JMVBOVeDOVYJHto,
|
|
369
369
|
nucliadb/writer/tus/s3.py,sha256=vF0NkFTXiXhXq3bCVXXVV-ED38ECVoUeeYViP8uMqcU,8357
|
370
370
|
nucliadb/writer/tus/storage.py,sha256=ToqwjoYnjI4oIcwzkhha_MPxi-k4Jk3Lt55zRwaC1SM,2903
|
371
371
|
nucliadb/writer/tus/utils.py,sha256=MSdVbRsRSZVdkaum69_0wku7X3p5wlZf4nr6E0GMKbw,2556
|
372
|
-
nucliadb-6.4.0.
|
373
|
-
nucliadb-6.4.0.
|
374
|
-
nucliadb-6.4.0.
|
375
|
-
nucliadb-6.4.0.
|
376
|
-
nucliadb-6.4.0.
|
372
|
+
nucliadb-6.4.0.post4210.dist-info/METADATA,sha256=SB9gIMgWxoWNtUEexRLH85E0PL-MnroGhJ6aOambTT4,4223
|
373
|
+
nucliadb-6.4.0.post4210.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
374
|
+
nucliadb-6.4.0.post4210.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
|
375
|
+
nucliadb-6.4.0.post4210.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
|
376
|
+
nucliadb-6.4.0.post4210.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|