nucliadb 6.3.7.post4066__py3-none-any.whl → 6.3.7.post4068__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.
@@ -0,0 +1,249 @@
1
+ # Copyright (C) 2021 Bosutech XXI S.L.
2
+ #
3
+ # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
+ # For commercial licensing, contact us at info@nuclia.com.
5
+ #
6
+ # AGPL:
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as
9
+ # published by the Free Software Foundation, either version 3 of the
10
+ # License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General Public License
18
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ #
20
+ from typing import Optional
21
+
22
+ from nucliadb.search.search.metrics import query_parser_observer
23
+ from nucliadb.search.search.query import expand_entities
24
+ from nucliadb.search.search.query_parser.exceptions import InvalidQueryError
25
+ from nucliadb.search.search.query_parser.fetcher import Fetcher
26
+ from nucliadb.search.search.query_parser.filter_expression import parse_expression
27
+ from nucliadb.search.search.query_parser.models import (
28
+ Filters,
29
+ NoopReranker,
30
+ ParsedQuery,
31
+ Query,
32
+ RankFusion,
33
+ RelationQuery,
34
+ UnitRetrieval,
35
+ _TextQuery,
36
+ )
37
+ from nucliadb.search.search.query_parser.old_filters import OldFilterParams, parse_old_filters
38
+ from nucliadb.search.search.utils import filter_hidden_resources
39
+ from nucliadb_models import search as search_models
40
+ from nucliadb_models.filters import FilterExpression
41
+ from nucliadb_models.search import (
42
+ SearchRequest,
43
+ SortField,
44
+ SortOptions,
45
+ SortOrder,
46
+ )
47
+ from nucliadb_protos import nodereader_pb2, utils_pb2
48
+
49
+ from .common import parse_keyword_query, parse_semantic_query, parse_top_k, validate_base_request
50
+
51
+ INDEX_SORTABLE_FIELDS = [
52
+ SortField.CREATED,
53
+ SortField.MODIFIED,
54
+ ]
55
+
56
+
57
+ @query_parser_observer.wrap({"type": "parse_search"})
58
+ async def parse_search(
59
+ kbid: str, item: SearchRequest, *, fetcher: Optional[Fetcher] = None
60
+ ) -> ParsedQuery:
61
+ fetcher = fetcher or fetcher_for_search(kbid, item)
62
+ parser = _SearchParser(kbid, item, fetcher)
63
+ retrieval = await parser.parse()
64
+ return ParsedQuery(fetcher=fetcher, retrieval=retrieval, generation=None)
65
+
66
+
67
+ def fetcher_for_search(kbid: str, item: SearchRequest) -> Fetcher:
68
+ return Fetcher(
69
+ kbid=kbid,
70
+ query=item.query,
71
+ user_vector=item.vector,
72
+ vectorset=item.vectorset,
73
+ rephrase=item.rephrase,
74
+ rephrase_prompt=item.rephrase_prompt,
75
+ generative_model=None,
76
+ )
77
+
78
+
79
+ class _SearchParser:
80
+ def __init__(self, kbid: str, item: SearchRequest, fetcher: Fetcher):
81
+ self.kbid = kbid
82
+ self.item = item
83
+ self.fetcher = fetcher
84
+
85
+ # cached data while parsing
86
+ self._query: Optional[Query] = None
87
+ self._top_k: Optional[int] = None
88
+
89
+ async def parse(self) -> UnitRetrieval:
90
+ validate_base_request(self.item)
91
+
92
+ self._top_k = parse_top_k(self.item)
93
+
94
+ # parse search types (features)
95
+
96
+ self._query = Query()
97
+
98
+ if search_models.SearchOptions.KEYWORD in self.item.features:
99
+ keyword = await self._parse_text_query()
100
+ self._query.keyword = keyword
101
+
102
+ if search_models.SearchOptions.FULLTEXT in self.item.features:
103
+ # copy from keyword, as everything is the same and we can't search
104
+ # anything different right now
105
+ keyword = self._query.keyword or (await self._parse_text_query())
106
+ self._query.fulltext = keyword
107
+
108
+ if search_models.SearchOptions.SEMANTIC in self.item.features:
109
+ self._query.semantic = await parse_semantic_query(self.item, fetcher=self.fetcher)
110
+
111
+ if search_models.SearchOptions.RELATIONS in self.item.features:
112
+ self._query.relation = await self._parse_relation_query()
113
+
114
+ filters = await self._parse_filters()
115
+
116
+ return UnitRetrieval(
117
+ query=self._query,
118
+ top_k=self._top_k,
119
+ filters=filters,
120
+ # TODO: this should be in a post retrieval step
121
+ rank_fusion=RankFusion(window=self._top_k),
122
+ reranker=NoopReranker(),
123
+ )
124
+
125
+ async def _parse_text_query(self) -> _TextQuery:
126
+ assert self._top_k is not None, "top_k must be parsed before text query"
127
+
128
+ keyword = await parse_keyword_query(self.item, fetcher=self.fetcher)
129
+ sort, order_by, limit = self._parse_sorting()
130
+ keyword.sort = sort
131
+ keyword.order_by = order_by
132
+ if limit is not None:
133
+ # sort limit can extend top_k
134
+ self._top_k = max(self._top_k, limit)
135
+ return keyword
136
+
137
+ async def _parse_relation_query(self) -> RelationQuery:
138
+ detected_entities = await self._get_detected_entities()
139
+ deleted_entity_groups = await self.fetcher.get_deleted_entity_groups()
140
+ meta_cache = await self.fetcher.get_entities_meta_cache()
141
+ deleted_entities = meta_cache.deleted_entities
142
+ return RelationQuery(
143
+ detected_entities=detected_entities,
144
+ deleted_entity_groups=deleted_entity_groups,
145
+ deleted_entities=deleted_entities,
146
+ )
147
+
148
+ async def _get_detected_entities(self) -> list[utils_pb2.RelationNode]:
149
+ detected_entities = await self.fetcher.get_detected_entities()
150
+ meta_cache = await self.fetcher.get_entities_meta_cache()
151
+ detected_entities = expand_entities(meta_cache, detected_entities)
152
+ return detected_entities
153
+
154
+ def _parse_sorting(self) -> tuple[search_models.SortOrder, search_models.SortField, Optional[int]]:
155
+ sort = self.item.sort
156
+ if len(self.item.query) == 0:
157
+ if sort is None:
158
+ sort = SortOptions(
159
+ field=SortField.CREATED,
160
+ order=SortOrder.DESC,
161
+ limit=None,
162
+ )
163
+ elif sort.field not in INDEX_SORTABLE_FIELDS:
164
+ raise InvalidQueryError(
165
+ "sort_field",
166
+ f"Empty query can only be sorted by '{SortField.CREATED}' or"
167
+ f" '{SortField.MODIFIED}' and sort limit won't be applied",
168
+ )
169
+ else:
170
+ if sort is None:
171
+ sort = SortOptions(
172
+ field=SortField.SCORE,
173
+ order=SortOrder.DESC,
174
+ limit=None,
175
+ )
176
+ elif sort.field not in INDEX_SORTABLE_FIELDS and sort.limit is None:
177
+ raise InvalidQueryError(
178
+ "sort_field",
179
+ f"Sort by '{sort.field}' requires setting a sort limit",
180
+ )
181
+
182
+ # We need to ask for all and cut later
183
+ top_k = None
184
+ if sort and sort.limit is not None:
185
+ # As the index can't sort, we have to do it when merging. To
186
+ # have consistent results, we must limit them
187
+ top_k = sort.limit
188
+
189
+ return (sort.order, sort.field, top_k)
190
+
191
+ async def _parse_filters(self) -> Filters:
192
+ assert self._query is not None, "query must be parsed before filters"
193
+
194
+ has_old_filters = (
195
+ len(self.item.filters) > 0
196
+ or len(self.item.fields) > 0
197
+ or self.item.range_creation_start is not None
198
+ or self.item.range_creation_end is not None
199
+ or self.item.range_modification_start is not None
200
+ or self.item.range_modification_end is not None
201
+ )
202
+ if self.item.filter_expression is not None and has_old_filters:
203
+ raise InvalidQueryError("filter_expression", "Cannot mix old filters with filter_expression")
204
+
205
+ field_expr = None
206
+ paragraph_expr = None
207
+ filter_operator = nodereader_pb2.FilterOperator.AND
208
+
209
+ if has_old_filters:
210
+ old_filters = OldFilterParams(
211
+ label_filters=self.item.filters,
212
+ keyword_filters=[],
213
+ range_creation_start=self.item.range_creation_start,
214
+ range_creation_end=self.item.range_creation_end,
215
+ range_modification_start=self.item.range_modification_start,
216
+ range_modification_end=self.item.range_modification_end,
217
+ fields=self.item.fields,
218
+ )
219
+ field_expr, paragraph_expr = await parse_old_filters(old_filters, self.fetcher)
220
+
221
+ if self.item.filter_expression is not None:
222
+ if self.item.filter_expression.field:
223
+ field_expr = await parse_expression(self.item.filter_expression.field, self.kbid)
224
+ if self.item.filter_expression.paragraph:
225
+ paragraph_expr = await parse_expression(self.item.filter_expression.paragraph, self.kbid)
226
+ if self.item.filter_expression.operator == FilterExpression.Operator.OR:
227
+ filter_operator = nodereader_pb2.FilterOperator.OR
228
+ else:
229
+ filter_operator = nodereader_pb2.FilterOperator.AND
230
+
231
+ autofilter = None
232
+ if self.item.autofilter:
233
+ if self._query.relation is not None:
234
+ autofilter = self._query.relation.detected_entities
235
+ else:
236
+ autofilter = await self._get_detected_entities()
237
+
238
+ hidden = await filter_hidden_resources(self.kbid, self.item.show_hidden)
239
+
240
+ return Filters(
241
+ autofilter=autofilter,
242
+ facets=self.item.faceted,
243
+ field_expression=field_expr,
244
+ paragraph_expression=paragraph_expr,
245
+ filter_expression_operator=filter_operator,
246
+ security=self.item.security,
247
+ hidden=hidden,
248
+ with_duplicates=self.item.with_duplicates,
249
+ )
@@ -0,0 +1,176 @@
1
+ # Copyright (C) 2021 Bosutech XXI S.L.
2
+ #
3
+ # nucliadb is offered under the AGPL v3.0 and as commercial software.
4
+ # For commercial licensing, contact us at info@nuclia.com.
5
+ #
6
+ # AGPL:
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as
9
+ # published by the Free Software Foundation, either version 3 of the
10
+ # License, or (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General Public License
18
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ #
20
+ from typing import Optional
21
+
22
+ from nucliadb.search.search.filters import (
23
+ translate_label,
24
+ )
25
+ from nucliadb.search.search.metrics import (
26
+ node_features,
27
+ query_parser_observer,
28
+ )
29
+ from nucliadb.search.search.query import (
30
+ apply_entities_filter,
31
+ get_sort_field_proto,
32
+ )
33
+ from nucliadb.search.search.query_parser.filter_expression import add_and_expression
34
+ from nucliadb.search.search.query_parser.models import ParsedQuery, PredictReranker, UnitRetrieval
35
+ from nucliadb_models.labels import LABEL_HIDDEN, translate_system_to_alias_label
36
+ from nucliadb_models.search import (
37
+ SortOrderMap,
38
+ )
39
+ from nucliadb_protos import nodereader_pb2, utils_pb2
40
+ from nucliadb_protos.nodereader_pb2 import SearchRequest
41
+
42
+
43
+ @query_parser_observer.wrap({"type": "convert_retrieval_to_proto"})
44
+ async def convert_retrieval_to_proto(
45
+ parsed: ParsedQuery,
46
+ ) -> tuple[SearchRequest, bool, list[str], Optional[str]]:
47
+ request = SearchRequest()
48
+
49
+ ## queries
50
+
51
+ if parsed.retrieval.query.keyword and parsed.retrieval.query.fulltext:
52
+ assert parsed.retrieval.query.keyword == parsed.retrieval.query.fulltext, (
53
+ "search proto doesn't support different queries for fulltext and keyword search"
54
+ )
55
+
56
+ if parsed.retrieval.query.fulltext:
57
+ request.document = True
58
+ node_features.inc({"type": "documents"})
59
+ if parsed.retrieval.query.keyword:
60
+ request.paragraph = True
61
+ node_features.inc({"type": "paragraphs"})
62
+
63
+ text_query = parsed.retrieval.query.keyword or parsed.retrieval.query.fulltext
64
+ if text_query is not None:
65
+ request.min_score_bm25 = text_query.min_score
66
+
67
+ if text_query.is_synonyms_query:
68
+ request.advanced_query = text_query.query
69
+ else:
70
+ request.body = text_query.query
71
+
72
+ # sort order
73
+ sort_field = get_sort_field_proto(text_query.order_by)
74
+ if sort_field is not None:
75
+ request.order.sort_by = sort_field
76
+ request.order.type = SortOrderMap[text_query.sort] # type: ignore
77
+
78
+ if parsed.retrieval.query.semantic:
79
+ node_features.inc({"type": "vectors"})
80
+
81
+ request.min_score_semantic = parsed.retrieval.query.semantic.min_score
82
+
83
+ query_vector = parsed.retrieval.query.semantic.query
84
+ if query_vector is not None:
85
+ request.vectorset = parsed.retrieval.query.semantic.vectorset
86
+ request.vector.extend(query_vector)
87
+
88
+ if parsed.retrieval.query.relation:
89
+ node_features.inc({"type": "relations"})
90
+
91
+ request.relation_subgraph.entry_points.extend(parsed.retrieval.query.relation.detected_entities)
92
+ request.relation_subgraph.depth = 1
93
+ request.relation_subgraph.deleted_groups.extend(
94
+ parsed.retrieval.query.relation.deleted_entity_groups
95
+ )
96
+ for group_id, deleted_entities in parsed.retrieval.query.relation.deleted_entities.items():
97
+ request.relation_subgraph.deleted_entities.append(
98
+ nodereader_pb2.EntitiesSubgraphRequest.DeletedEntities(
99
+ node_subtype=group_id, node_values=deleted_entities
100
+ )
101
+ )
102
+
103
+ # filters
104
+
105
+ request.with_duplicates = parsed.retrieval.filters.with_duplicates
106
+
107
+ request.faceted.labels.extend([translate_label(facet) for facet in parsed.retrieval.filters.facets])
108
+
109
+ if (
110
+ parsed.retrieval.filters.security is not None
111
+ and len(parsed.retrieval.filters.security.groups) > 0
112
+ ):
113
+ security_pb = utils_pb2.Security()
114
+ for group_id in parsed.retrieval.filters.security.groups:
115
+ if group_id not in security_pb.access_groups:
116
+ security_pb.access_groups.append(group_id)
117
+ request.security.CopyFrom(security_pb)
118
+
119
+ if parsed.retrieval.filters.field_expression:
120
+ request.field_filter.CopyFrom(parsed.retrieval.filters.field_expression)
121
+ if parsed.retrieval.filters.paragraph_expression:
122
+ request.paragraph_filter.CopyFrom(parsed.retrieval.filters.paragraph_expression)
123
+ request.filter_operator = parsed.retrieval.filters.filter_expression_operator
124
+
125
+ autofilter = []
126
+ if parsed.retrieval.filters.autofilter:
127
+ entity_filters = apply_entities_filter(request, parsed.retrieval.filters.autofilter)
128
+ autofilter.extend([translate_system_to_alias_label(e) for e in entity_filters])
129
+
130
+ if parsed.retrieval.filters.hidden is not None:
131
+ expr = nodereader_pb2.FilterExpression()
132
+ if parsed.retrieval.filters.hidden:
133
+ expr.facet.facet = LABEL_HIDDEN
134
+ else:
135
+ expr.bool_not.facet.facet = LABEL_HIDDEN
136
+
137
+ add_and_expression(request.field_filter, expr)
138
+
139
+ # top_k
140
+
141
+ # Adjust requested page size depending on rank fusion and reranking algorithms.
142
+ #
143
+ # Some rerankers want more results than the requested by the user so
144
+ # reranking can have more choices.
145
+
146
+ rank_fusion_window = 0
147
+ if parsed.retrieval.rank_fusion is not None:
148
+ rank_fusion_window = parsed.retrieval.rank_fusion.window
149
+
150
+ reranker_window = 0
151
+ if parsed.retrieval.reranker is not None and isinstance(parsed.retrieval.reranker, PredictReranker):
152
+ reranker_window = parsed.retrieval.reranker.window
153
+
154
+ request.result_per_page = max(
155
+ request.result_per_page,
156
+ rank_fusion_window,
157
+ reranker_window,
158
+ )
159
+
160
+ # XXX: legacy values that were returned by QueryParser but not always
161
+ # needed. We should find a better abstraction
162
+
163
+ incomplete = is_incomplete(parsed.retrieval)
164
+
165
+ rephrased_query = None
166
+ if parsed.retrieval.query.semantic:
167
+ rephrased_query = await parsed.fetcher.get_rephrased_query()
168
+
169
+ return request, incomplete, autofilter, rephrased_query
170
+
171
+
172
+ def is_incomplete(retrieval: UnitRetrieval) -> bool:
173
+ if retrieval.query.semantic is None:
174
+ return False
175
+ incomplete = retrieval.query.semantic.query is None or len(retrieval.query.semantic.query) == 0
176
+ return incomplete
@@ -178,8 +178,10 @@ def get_reranker(reranker: parser_models.Reranker) -> Reranker:
178
178
  elif isinstance(reranker, parser_models.PredictReranker):
179
179
  algorithm = PredictReranker(reranker.window)
180
180
 
181
- else:
182
- raise ValueError(f"Unknown reranker requested: {reranker}")
181
+ else: # pragma: nocover
182
+ # This is a trick so mypy generates an error if this branch can be reached,
183
+ # that is, if we are missing some ifs
184
+ _a: int = "a"
183
185
 
184
186
  return algorithm
185
187
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nucliadb
3
- Version: 6.3.7.post4066
3
+ Version: 6.3.7.post4068
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.3.7.post4066
24
- Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.7.post4066
25
- Requires-Dist: nucliadb-protos>=6.3.7.post4066
26
- Requires-Dist: nucliadb-models>=6.3.7.post4066
27
- Requires-Dist: nidx-protos>=6.3.7.post4066
23
+ Requires-Dist: nucliadb-telemetry[all]>=6.3.7.post4068
24
+ Requires-Dist: nucliadb-utils[cache,fastapi,storages]>=6.3.7.post4068
25
+ Requires-Dist: nucliadb-protos>=6.3.7.post4068
26
+ Requires-Dist: nucliadb-models>=6.3.7.post4068
27
+ Requires-Dist: nidx-protos>=6.3.7.post4068
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]
@@ -216,7 +216,7 @@ nucliadb/search/api/v1/graph.py,sha256=ItVpzJbqfDLjoIo2fTb2mKGCM1Z34sx7CBb3gNmj6
216
216
  nucliadb/search/api/v1/knowledgebox.py,sha256=rWhx3PYWryingu19qwwFDbVvVYynq5Ky23FSlzmTutQ,8721
217
217
  nucliadb/search/api/v1/predict_proxy.py,sha256=QrGzo0hKjtmyGZ6pjlJHYAh4hxwVUIOTcVcerRCw7eE,3047
218
218
  nucliadb/search/api/v1/router.py,sha256=mtT07rBZcVfpa49doaw9b1tj3sdi3qLH0gn9Io6NYM0,988
219
- nucliadb/search/api/v1/search.py,sha256=4WDuY0LdxycWX960MGUV5Yojnq2V5A5hxDnfaEsTW9Q,13985
219
+ nucliadb/search/api/v1/search.py,sha256=9OR4jXryhDkTFCPeeXyxK_VKGKkUMn8i5q41f747AiI,12829
220
220
  nucliadb/search/api/v1/suggest.py,sha256=Pwyxyk3Vu7aKU8vl2_rKhuE40ngnjZwAXS1rAilPDtM,6506
221
221
  nucliadb/search/api/v1/summarize.py,sha256=VAHJvE6V3xUgEBfqNKhgoxmDqCvh30RnrEIBVhMcNLU,2499
222
222
  nucliadb/search/api/v1/utils.py,sha256=5Ve-frn7LAE2jqAgB85F8RSeqxDlyA08--gS-AdOLS4,1434
@@ -233,39 +233,43 @@ nucliadb/search/search/cut.py,sha256=ytY0_GY7ocNjfxTb4aosxEp4ZfhQNDP--JkhEMGD298
233
233
  nucliadb/search/search/exceptions.py,sha256=klGLgAGGrXcSGix_W6418ZBMqDchAIGjN77ofkOScEI,1039
234
234
  nucliadb/search/search/fetch.py,sha256=XJHIFnZmXM_8Kb37lb4lg1GYG7cZ1plT-qAIb_QziX4,6184
235
235
  nucliadb/search/search/filters.py,sha256=1MkHlJjAQqoRCj7e5cEzK2HvBxGLE17I_omsjiklbtw,6476
236
- nucliadb/search/search/find.py,sha256=dGzk6gDN6xdtREhLcZxBX_rTppQ8O1WcSYJQE4r5h-o,10372
237
- nucliadb/search/search/find_merge.py,sha256=3FnzKFEnVemg6FO_6zveulbAU7klvsiPEBvLrpBBMg8,17450
236
+ nucliadb/search/search/find.py,sha256=d3OufK9xPaGgSQ9RzER6VJ_rk-d_uly4ia452wmGiz8,8182
237
+ nucliadb/search/search/find_merge.py,sha256=sS_0ZeTDs7AiWWuDmYos8mThG5XvaTE92DBoQOPHGTQ,17964
238
238
  nucliadb/search/search/graph_merge.py,sha256=OiUNiXOWwrUVKqStuRcoUJwvDbDYamqIgiAy_FwPdMI,3405
239
- nucliadb/search/search/graph_strategy.py,sha256=SPJdDHQcTFsNb1IEWdWzklC5j1Vv9igibo0dYQAgcy0,33113
239
+ nucliadb/search/search/graph_strategy.py,sha256=hwof-jxYELI6EYmvccDViDda3urE6E7v24-_-IsEF3E,32916
240
240
  nucliadb/search/search/hydrator.py,sha256=-R37gCrGxkyaiHQalnTWHNG_FCx11Zucd7qA1vQCxuw,6985
241
241
  nucliadb/search/search/ingestion_agents.py,sha256=NeJr4EEX-bvFFMGvXOOwLv8uU7NuQ-ntJnnrhnKfMzY,3174
242
- nucliadb/search/search/merge.py,sha256=fh5WnA_xnXp-Iiq5Cud9hIGole7_0OW2b3Oymk32D6Y,22689
242
+ nucliadb/search/search/merge.py,sha256=4tnTgljD7FKdQYX7frZ3qyu8-n9wNb7f6H6ulqq4sV8,23369
243
243
  nucliadb/search/search/metrics.py,sha256=HJVQPLOIwLuc733G4keqEgx1-Dcg97hyWGKZQTojiSE,2973
244
244
  nucliadb/search/search/paragraphs.py,sha256=pNAEiYqJGGUVcEf7xf-PFMVqz0PX4Qb-WNG-_zPGN2o,7799
245
245
  nucliadb/search/search/pgcatalog.py,sha256=s_J98fsX_RuFXwpejpkGqG-tD9ELuzz4YQ6U3ew5h2g,9313
246
246
  nucliadb/search/search/predict_proxy.py,sha256=IFI3v_ODz2_UU1XZnyaD391fE7-2C0npSmj_HmDvzS4,3123
247
- nucliadb/search/search/query.py,sha256=Obd84og7BQJ5zZd3iAc9kyndCTHv0ihSL3PO5GNljR4,30351
247
+ nucliadb/search/search/query.py,sha256=B7KJCG1d4oX4M2WlecCuMc98QCygutsl1R980HyVx3M,11491
248
248
  nucliadb/search/search/rank_fusion.py,sha256=tRGo_KlsFsVx1CQEy1iqQ6f0T1Dq1kf0axDXHuuzvvM,6946
249
- nucliadb/search/search/rerankers.py,sha256=3vep4EOVNeDJGsMdx-1g6Ar4ZGJG3IHym3HkxnbwtAQ,7321
249
+ nucliadb/search/search/rerankers.py,sha256=PvhExUb8zZYghiFHRgGotw6h6bU--Rft09wE8arvtAw,7424
250
250
  nucliadb/search/search/shards.py,sha256=OEtN1p9WX_cMX8t-myaafpmFAPTpUEOutR7z1sDuNcY,3242
251
251
  nucliadb/search/search/summarize.py,sha256=ksmYPubEQvAQgfPdZHfzB_rR19B2ci4IYZ6jLdHxZo8,4996
252
252
  nucliadb/search/search/utils.py,sha256=iF2tbBA56gRMJH1TlE2hMrqeXqjoeOPt4KgRdp2m9Ek,3313
253
253
  nucliadb/search/search/chat/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
254
- nucliadb/search/search/chat/ask.py,sha256=OLZOfVKAJmnVW7KiKIfDVjYJphkDRd7cMa5NwUQbT-8,37421
254
+ nucliadb/search/search/chat/ask.py,sha256=nGReEt6MRfBibMxWuH3H7jw5ktK3OmSW9ixzx-CC23Y,37229
255
255
  nucliadb/search/search/chat/exceptions.py,sha256=Siy4GXW2L7oPhIR86H3WHBhE9lkV4A4YaAszuGGUf54,1356
256
256
  nucliadb/search/search/chat/images.py,sha256=PA8VWxT5_HUGfW1ULhKTK46UBsVyINtWWqEM1ulzX1E,3095
257
257
  nucliadb/search/search/chat/prompt.py,sha256=Jnja-Ss7skgnnDY8BymVfdeYsFPnIQFL8tEvcRXTKUE,47356
258
- nucliadb/search/search/chat/query.py,sha256=ILWdd-0kaV97kR4wenwo4lX9K0GN-dXv957wL4CKvx8,16779
258
+ nucliadb/search/search/chat/query.py,sha256=ScZd2-hX9m36A8JGxesN8F5NKZV4FTiF-tN585gxg1M,16806
259
259
  nucliadb/search/search/query_parser/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
260
260
  nucliadb/search/search/query_parser/exceptions.py,sha256=szAOXUZ27oNY-OSa9t2hQ5HHkQQC0EX1FZz_LluJHJE,1224
261
- nucliadb/search/search/query_parser/fetcher.py,sha256=vrPgPnebWlrbx9fcelw7eHayEDptxnm9BP1F9LAEMws,15307
261
+ nucliadb/search/search/query_parser/fetcher.py,sha256=SkvBRDfSKmuz-QygNKLAU4AhZhhDo1dnOZmt1zA28RA,16851
262
262
  nucliadb/search/search/query_parser/filter_expression.py,sha256=rws5vsKTofX2iMUK4yvjmLZFxtcbWbyhIcwen4j0rQg,6578
263
- nucliadb/search/search/query_parser/models.py,sha256=7czH-jHskl9axEnZV5XnQY8cyN_fs14Cpivzd5aaSxc,2686
263
+ nucliadb/search/search/query_parser/models.py,sha256=gGE2E8mfzJ49rOkgBtyYrax2O9mZUYoH7iyxP5IhotU,4651
264
264
  nucliadb/search/search/query_parser/old_filters.py,sha256=-zbfN-RsXoj_DRjh3Lfp-wShwFXgkISawzVptVzja-A,9071
265
265
  nucliadb/search/search/query_parser/parsers/__init__.py,sha256=ySCNSdbesLXGZyR88919njulA6UE10_3PhqMG_Yj1o4,1034
266
+ nucliadb/search/search/query_parser/parsers/ask.py,sha256=eTz8wS-EJHuAagR384h6TT64itymFZRpfZJGX8r6aZM,2771
266
267
  nucliadb/search/search/query_parser/parsers/catalog.py,sha256=XdBiTweGTQkj8m_V_i2xbwp7P5pPO8K1Tud692XKhMw,7149
267
- nucliadb/search/search/query_parser/parsers/find.py,sha256=5Hp3MIlzkf_NdzpBaNAIHS8gWm6CYZEzUMwmrrO9Z-k,4783
268
+ nucliadb/search/search/query_parser/parsers/common.py,sha256=InUWq5cL_LBDptuibQiSMw-9OeByqymTTqW0dzp7rM0,6265
269
+ nucliadb/search/search/query_parser/parsers/find.py,sha256=MHEcFcukGUT8UMeq3wmefnv-FIEslrLsGNrDjtSvQ5A,11262
268
270
  nucliadb/search/search/query_parser/parsers/graph.py,sha256=QJs-pybNXPsMSEkIHctb0Q0xQG-aArks8BtUxbJL5rU,9386
271
+ nucliadb/search/search/query_parser/parsers/search.py,sha256=Qh_xVdLW-jGyD2xDfiRU0K7vDuPu_3JsZEWJn81TLHw,9805
272
+ nucliadb/search/search/query_parser/parsers/unit_retrieval.py,sha256=2NS11DnSUqj3A58mZVMsVRkH00ah9S1lXgUvJZF8NCI,6773
269
273
  nucliadb/standalone/__init__.py,sha256=cp15ZcFnHvpcu_5-aK2A4uUyvuZVV_MJn4bIXMa20ks,835
270
274
  nucliadb/standalone/api_router.py,sha256=hgq9FXpihzgjHkwcVGfGCSwyXy67fqXTfLFHuINzIi0,5567
271
275
  nucliadb/standalone/app.py,sha256=mAApNK_iVsQgJyd-mtwCeZq5csSimwnXmlQGH9a70pE,5586
@@ -361,8 +365,8 @@ nucliadb/writer/tus/local.py,sha256=7jYa_w9b-N90jWgN2sQKkNcomqn6JMVBOVeDOVYJHto,
361
365
  nucliadb/writer/tus/s3.py,sha256=vF0NkFTXiXhXq3bCVXXVV-ED38ECVoUeeYViP8uMqcU,8357
362
366
  nucliadb/writer/tus/storage.py,sha256=ToqwjoYnjI4oIcwzkhha_MPxi-k4Jk3Lt55zRwaC1SM,2903
363
367
  nucliadb/writer/tus/utils.py,sha256=MSdVbRsRSZVdkaum69_0wku7X3p5wlZf4nr6E0GMKbw,2556
364
- nucliadb-6.3.7.post4066.dist-info/METADATA,sha256=T8ZXH-p7B8m-0u_vcif1of80-FT3pbxg4vfITXBMUno,4301
365
- nucliadb-6.3.7.post4066.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
366
- nucliadb-6.3.7.post4066.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
367
- nucliadb-6.3.7.post4066.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
368
- nucliadb-6.3.7.post4066.dist-info/RECORD,,
368
+ nucliadb-6.3.7.post4068.dist-info/METADATA,sha256=5s-XgWMQEi0Ea8TUODlJ7Us6DomG6DTvnWvJneE2I3Y,4301
369
+ nucliadb-6.3.7.post4068.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
370
+ nucliadb-6.3.7.post4068.dist-info/entry_points.txt,sha256=XqGfgFDuY3zXQc8ewXM2TRVjTModIq851zOsgrmaXx4,1268
371
+ nucliadb-6.3.7.post4068.dist-info/top_level.txt,sha256=hwYhTVnX7jkQ9gJCkVrbqEG1M4lT2F_iPQND1fCzF80,20
372
+ nucliadb-6.3.7.post4068.dist-info/RECORD,,