usecortex-ai 0.1.0__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.
Files changed (89) hide show
  1. cortex_ai/__init__.py +103 -0
  2. cortex_ai/client.py +244 -0
  3. cortex_ai/core/__init__.py +52 -0
  4. cortex_ai/core/api_error.py +23 -0
  5. cortex_ai/core/client_wrapper.py +84 -0
  6. cortex_ai/core/datetime_utils.py +28 -0
  7. cortex_ai/core/file.py +67 -0
  8. cortex_ai/core/force_multipart.py +18 -0
  9. cortex_ai/core/http_client.py +543 -0
  10. cortex_ai/core/http_response.py +55 -0
  11. cortex_ai/core/jsonable_encoder.py +100 -0
  12. cortex_ai/core/pydantic_utilities.py +258 -0
  13. cortex_ai/core/query_encoder.py +58 -0
  14. cortex_ai/core/remove_none_from_dict.py +11 -0
  15. cortex_ai/core/request_options.py +35 -0
  16. cortex_ai/core/serialization.py +276 -0
  17. cortex_ai/embeddings/__init__.py +4 -0
  18. cortex_ai/embeddings/client.py +442 -0
  19. cortex_ai/embeddings/raw_client.py +1153 -0
  20. cortex_ai/environment.py +7 -0
  21. cortex_ai/errors/__init__.py +21 -0
  22. cortex_ai/errors/bad_request_error.py +11 -0
  23. cortex_ai/errors/forbidden_error.py +11 -0
  24. cortex_ai/errors/internal_server_error.py +11 -0
  25. cortex_ai/errors/not_found_error.py +11 -0
  26. cortex_ai/errors/service_unavailable_error.py +11 -0
  27. cortex_ai/errors/unauthorized_error.py +11 -0
  28. cortex_ai/errors/unprocessable_entity_error.py +10 -0
  29. cortex_ai/fetch/__init__.py +4 -0
  30. cortex_ai/fetch/client.py +143 -0
  31. cortex_ai/fetch/raw_client.py +310 -0
  32. cortex_ai/raw_client.py +90 -0
  33. cortex_ai/search/__init__.py +7 -0
  34. cortex_ai/search/client.py +536 -0
  35. cortex_ai/search/raw_client.py +1064 -0
  36. cortex_ai/search/types/__init__.py +7 -0
  37. cortex_ai/search/types/alpha.py +5 -0
  38. cortex_ai/sources/__init__.py +4 -0
  39. cortex_ai/sources/client.py +187 -0
  40. cortex_ai/sources/raw_client.py +532 -0
  41. cortex_ai/tenant/__init__.py +4 -0
  42. cortex_ai/tenant/client.py +120 -0
  43. cortex_ai/tenant/raw_client.py +283 -0
  44. cortex_ai/types/__init__.py +69 -0
  45. cortex_ai/types/actual_error_response.py +20 -0
  46. cortex_ai/types/app_sources_upload_data.py +22 -0
  47. cortex_ai/types/attachment_model.py +26 -0
  48. cortex_ai/types/batch_upload_data.py +22 -0
  49. cortex_ai/types/bm_25_operator_type.py +5 -0
  50. cortex_ai/types/content_model.py +26 -0
  51. cortex_ai/types/delete_memory_request.py +21 -0
  52. cortex_ai/types/embeddings_create_collection_data.py +22 -0
  53. cortex_ai/types/embeddings_delete_data.py +22 -0
  54. cortex_ai/types/embeddings_get_data.py +22 -0
  55. cortex_ai/types/embeddings_search_data.py +22 -0
  56. cortex_ai/types/error_response.py +22 -0
  57. cortex_ai/types/extended_context.py +20 -0
  58. cortex_ai/types/fetch_content_data.py +23 -0
  59. cortex_ai/types/file_upload_result.py +20 -0
  60. cortex_ai/types/full_text_search_data.py +22 -0
  61. cortex_ai/types/http_validation_error.py +20 -0
  62. cortex_ai/types/list_sources_response.py +22 -0
  63. cortex_ai/types/markdown_upload_request.py +21 -0
  64. cortex_ai/types/processing_status.py +22 -0
  65. cortex_ai/types/related_chunk.py +22 -0
  66. cortex_ai/types/search_chunk.py +34 -0
  67. cortex_ai/types/search_data.py +22 -0
  68. cortex_ai/types/single_upload_data.py +21 -0
  69. cortex_ai/types/source.py +32 -0
  70. cortex_ai/types/source_content.py +26 -0
  71. cortex_ai/types/source_model.py +32 -0
  72. cortex_ai/types/tenant_create_data.py +22 -0
  73. cortex_ai/types/tenant_stats.py +23 -0
  74. cortex_ai/types/validation_error.py +22 -0
  75. cortex_ai/types/validation_error_loc_item.py +5 -0
  76. cortex_ai/upload/__init__.py +4 -0
  77. cortex_ai/upload/client.py +1572 -0
  78. cortex_ai/upload/raw_client.py +4202 -0
  79. cortex_ai/user/__init__.py +4 -0
  80. cortex_ai/user/client.py +125 -0
  81. cortex_ai/user/raw_client.py +300 -0
  82. cortex_ai/user_memory/__init__.py +4 -0
  83. cortex_ai/user_memory/client.py +443 -0
  84. cortex_ai/user_memory/raw_client.py +651 -0
  85. usecortex_ai-0.1.0.dist-info/METADATA +136 -0
  86. usecortex_ai-0.1.0.dist-info/RECORD +89 -0
  87. usecortex_ai-0.1.0.dist-info/WHEEL +5 -0
  88. usecortex_ai-0.1.0.dist-info/licenses/LICENSE +22 -0
  89. usecortex_ai-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1064 @@
1
+ # This file was auto-generated by Fern from our API Definition.
2
+
3
+ import typing
4
+ from json.decoder import JSONDecodeError
5
+
6
+ from ..core.api_error import ApiError
7
+ from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
8
+ from ..core.http_response import AsyncHttpResponse, HttpResponse
9
+ from ..core.pydantic_utilities import parse_obj_as
10
+ from ..core.request_options import RequestOptions
11
+ from ..core.serialization import convert_and_respect_annotation_metadata
12
+ from ..errors.bad_request_error import BadRequestError
13
+ from ..errors.forbidden_error import ForbiddenError
14
+ from ..errors.internal_server_error import InternalServerError
15
+ from ..errors.not_found_error import NotFoundError
16
+ from ..errors.service_unavailable_error import ServiceUnavailableError
17
+ from ..errors.unauthorized_error import UnauthorizedError
18
+ from ..errors.unprocessable_entity_error import UnprocessableEntityError
19
+ from ..types.actual_error_response import ActualErrorResponse
20
+ from ..types.bm_25_operator_type import Bm25OperatorType
21
+ from ..types.full_text_search_data import FullTextSearchData
22
+ from ..types.search_data import SearchData
23
+ from .types.alpha import Alpha
24
+
25
+ # this is used as the default value for optional parameters
26
+ OMIT = typing.cast(typing.Any, ...)
27
+
28
+
29
+ class RawSearchClient:
30
+ def __init__(self, *, client_wrapper: SyncClientWrapper):
31
+ self._client_wrapper = client_wrapper
32
+
33
+ def qna(
34
+ self,
35
+ *,
36
+ question: str,
37
+ session_id: str,
38
+ tenant_id: str,
39
+ context_list: typing.Optional[typing.Sequence[str]] = OMIT,
40
+ search_modes: typing.Optional[typing.Sequence[str]] = OMIT,
41
+ sub_tenant_id: typing.Optional[str] = OMIT,
42
+ highlight_chunks: typing.Optional[bool] = OMIT,
43
+ stream: typing.Optional[bool] = OMIT,
44
+ search_alpha: typing.Optional[float] = OMIT,
45
+ recency_bias: typing.Optional[float] = OMIT,
46
+ ai_generation: typing.Optional[bool] = OMIT,
47
+ top_n: typing.Optional[int] = OMIT,
48
+ user_name: typing.Optional[str] = OMIT,
49
+ user_instructions: typing.Optional[str] = OMIT,
50
+ multi_step_reasoning: typing.Optional[bool] = OMIT,
51
+ auto_agent_routing: typing.Optional[bool] = OMIT,
52
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
53
+ request_options: typing.Optional[RequestOptions] = None,
54
+ ) -> HttpResponse[typing.Optional[typing.Any]]:
55
+ """
56
+ Parameters
57
+ ----------
58
+ question : str
59
+
60
+ session_id : str
61
+
62
+ tenant_id : str
63
+
64
+ context_list : typing.Optional[typing.Sequence[str]]
65
+
66
+ search_modes : typing.Optional[typing.Sequence[str]]
67
+
68
+ sub_tenant_id : typing.Optional[str]
69
+
70
+ highlight_chunks : typing.Optional[bool]
71
+
72
+ stream : typing.Optional[bool]
73
+
74
+ search_alpha : typing.Optional[float]
75
+
76
+ recency_bias : typing.Optional[float]
77
+
78
+ ai_generation : typing.Optional[bool]
79
+
80
+ top_n : typing.Optional[int]
81
+
82
+ user_name : typing.Optional[str]
83
+
84
+ user_instructions : typing.Optional[str]
85
+
86
+ multi_step_reasoning : typing.Optional[bool]
87
+
88
+ auto_agent_routing : typing.Optional[bool]
89
+
90
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
91
+
92
+ request_options : typing.Optional[RequestOptions]
93
+ Request-specific configuration.
94
+
95
+ Returns
96
+ -------
97
+ HttpResponse[typing.Optional[typing.Any]]
98
+ Successful Response
99
+ """
100
+ _response = self._client_wrapper.httpx_client.request(
101
+ "search/qna",
102
+ method="POST",
103
+ json={
104
+ "question": question,
105
+ "session_id": session_id,
106
+ "tenant_id": tenant_id,
107
+ "context_list": context_list,
108
+ "search_modes": search_modes,
109
+ "sub_tenant_id": sub_tenant_id,
110
+ "highlight_chunks": highlight_chunks,
111
+ "stream": stream,
112
+ "search_alpha": search_alpha,
113
+ "recency_bias": recency_bias,
114
+ "ai_generation": ai_generation,
115
+ "top_n": top_n,
116
+ "user_name": user_name,
117
+ "user_instructions": user_instructions,
118
+ "multi_step_reasoning": multi_step_reasoning,
119
+ "auto_agent_routing": auto_agent_routing,
120
+ "metadata": metadata,
121
+ },
122
+ headers={
123
+ "content-type": "application/json",
124
+ },
125
+ request_options=request_options,
126
+ omit=OMIT,
127
+ )
128
+ try:
129
+ if _response is None or not _response.text.strip():
130
+ return HttpResponse(response=_response, data=None)
131
+ if 200 <= _response.status_code < 300:
132
+ _data = typing.cast(
133
+ typing.Optional[typing.Any],
134
+ parse_obj_as(
135
+ type_=typing.Optional[typing.Any], # type: ignore
136
+ object_=_response.json(),
137
+ ),
138
+ )
139
+ return HttpResponse(response=_response, data=_data)
140
+ if _response.status_code == 400:
141
+ raise BadRequestError(
142
+ headers=dict(_response.headers),
143
+ body=typing.cast(
144
+ ActualErrorResponse,
145
+ parse_obj_as(
146
+ type_=ActualErrorResponse, # type: ignore
147
+ object_=_response.json(),
148
+ ),
149
+ ),
150
+ )
151
+ if _response.status_code == 401:
152
+ raise UnauthorizedError(
153
+ headers=dict(_response.headers),
154
+ body=typing.cast(
155
+ ActualErrorResponse,
156
+ parse_obj_as(
157
+ type_=ActualErrorResponse, # type: ignore
158
+ object_=_response.json(),
159
+ ),
160
+ ),
161
+ )
162
+ if _response.status_code == 403:
163
+ raise ForbiddenError(
164
+ headers=dict(_response.headers),
165
+ body=typing.cast(
166
+ ActualErrorResponse,
167
+ parse_obj_as(
168
+ type_=ActualErrorResponse, # type: ignore
169
+ object_=_response.json(),
170
+ ),
171
+ ),
172
+ )
173
+ if _response.status_code == 404:
174
+ raise NotFoundError(
175
+ headers=dict(_response.headers),
176
+ body=typing.cast(
177
+ ActualErrorResponse,
178
+ parse_obj_as(
179
+ type_=ActualErrorResponse, # type: ignore
180
+ object_=_response.json(),
181
+ ),
182
+ ),
183
+ )
184
+ if _response.status_code == 422:
185
+ raise UnprocessableEntityError(
186
+ headers=dict(_response.headers),
187
+ body=typing.cast(
188
+ typing.Optional[typing.Any],
189
+ parse_obj_as(
190
+ type_=typing.Optional[typing.Any], # type: ignore
191
+ object_=_response.json(),
192
+ ),
193
+ ),
194
+ )
195
+ if _response.status_code == 500:
196
+ raise InternalServerError(
197
+ headers=dict(_response.headers),
198
+ body=typing.cast(
199
+ ActualErrorResponse,
200
+ parse_obj_as(
201
+ type_=ActualErrorResponse, # type: ignore
202
+ object_=_response.json(),
203
+ ),
204
+ ),
205
+ )
206
+ if _response.status_code == 503:
207
+ raise ServiceUnavailableError(
208
+ headers=dict(_response.headers),
209
+ body=typing.cast(
210
+ ActualErrorResponse,
211
+ parse_obj_as(
212
+ type_=ActualErrorResponse, # type: ignore
213
+ object_=_response.json(),
214
+ ),
215
+ ),
216
+ )
217
+ _response_json = _response.json()
218
+ except JSONDecodeError:
219
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
220
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
221
+
222
+ def retrieve(
223
+ self,
224
+ *,
225
+ query: str,
226
+ tenant_id: str,
227
+ sub_tenant_id: typing.Optional[str] = OMIT,
228
+ max_chunks: typing.Optional[int] = OMIT,
229
+ alpha: typing.Optional[Alpha] = OMIT,
230
+ recency_bias: typing.Optional[float] = OMIT,
231
+ num_related_chunks: typing.Optional[int] = OMIT,
232
+ request_options: typing.Optional[RequestOptions] = None,
233
+ ) -> HttpResponse[SearchData]:
234
+ """
235
+ Search for content within indexed sources using semantic and keyword search capabilities.
236
+
237
+ This endpoint performs a search query against the Findr backend, allowing users to retrieve
238
+ relevant content chunks from their indexed documents and sources. The search can be customized
239
+ with various parameters to control the number of results and search behavior.
240
+
241
+ Args:
242
+ request (SearchRequest): The search request containing:
243
+ - query (str): Search query string to find relevant content
244
+ - tenant_id (str, optional): Tenant identifier for multi-tenancy
245
+ - sub_tenant_id (str, optional): Sub-tenant identifier, defaults to tenant_id
246
+ - max_chunks (int, optional): Maximum number of content chunks to return
247
+ - alpha (Union[float, str], optional): Search algorithm parameter for result ranking (default: 0.8). Can be float-type (0.0-1.0) or 'auto' for dynamic selection
248
+ - recency_bias (float, optional): Bias towards more recent content (default: 0.5)
249
+ - num_related_chunks (int, optional): Number of related chunks to return (default: 0)
250
+ api_details (dict): Authentication details obtained from API key validation
251
+
252
+ Returns:
253
+ SearchData: Success response with search results
254
+
255
+ Parameters
256
+ ----------
257
+ query : str
258
+
259
+ tenant_id : str
260
+
261
+ sub_tenant_id : typing.Optional[str]
262
+
263
+ max_chunks : typing.Optional[int]
264
+
265
+ alpha : typing.Optional[Alpha]
266
+
267
+ recency_bias : typing.Optional[float]
268
+
269
+ num_related_chunks : typing.Optional[int]
270
+
271
+ request_options : typing.Optional[RequestOptions]
272
+ Request-specific configuration.
273
+
274
+ Returns
275
+ -------
276
+ HttpResponse[SearchData]
277
+ Successful Response
278
+ """
279
+ _response = self._client_wrapper.httpx_client.request(
280
+ "search/retrieve",
281
+ method="POST",
282
+ json={
283
+ "query": query,
284
+ "tenant_id": tenant_id,
285
+ "sub_tenant_id": sub_tenant_id,
286
+ "max_chunks": max_chunks,
287
+ "alpha": convert_and_respect_annotation_metadata(object_=alpha, annotation=Alpha, direction="write"),
288
+ "recency_bias": recency_bias,
289
+ "num_related_chunks": num_related_chunks,
290
+ },
291
+ headers={
292
+ "content-type": "application/json",
293
+ },
294
+ request_options=request_options,
295
+ omit=OMIT,
296
+ )
297
+ try:
298
+ if 200 <= _response.status_code < 300:
299
+ _data = typing.cast(
300
+ SearchData,
301
+ parse_obj_as(
302
+ type_=SearchData, # type: ignore
303
+ object_=_response.json(),
304
+ ),
305
+ )
306
+ return HttpResponse(response=_response, data=_data)
307
+ if _response.status_code == 400:
308
+ raise BadRequestError(
309
+ headers=dict(_response.headers),
310
+ body=typing.cast(
311
+ ActualErrorResponse,
312
+ parse_obj_as(
313
+ type_=ActualErrorResponse, # type: ignore
314
+ object_=_response.json(),
315
+ ),
316
+ ),
317
+ )
318
+ if _response.status_code == 401:
319
+ raise UnauthorizedError(
320
+ headers=dict(_response.headers),
321
+ body=typing.cast(
322
+ ActualErrorResponse,
323
+ parse_obj_as(
324
+ type_=ActualErrorResponse, # type: ignore
325
+ object_=_response.json(),
326
+ ),
327
+ ),
328
+ )
329
+ if _response.status_code == 403:
330
+ raise ForbiddenError(
331
+ headers=dict(_response.headers),
332
+ body=typing.cast(
333
+ ActualErrorResponse,
334
+ parse_obj_as(
335
+ type_=ActualErrorResponse, # type: ignore
336
+ object_=_response.json(),
337
+ ),
338
+ ),
339
+ )
340
+ if _response.status_code == 404:
341
+ raise NotFoundError(
342
+ headers=dict(_response.headers),
343
+ body=typing.cast(
344
+ ActualErrorResponse,
345
+ parse_obj_as(
346
+ type_=ActualErrorResponse, # type: ignore
347
+ object_=_response.json(),
348
+ ),
349
+ ),
350
+ )
351
+ if _response.status_code == 422:
352
+ raise UnprocessableEntityError(
353
+ headers=dict(_response.headers),
354
+ body=typing.cast(
355
+ typing.Optional[typing.Any],
356
+ parse_obj_as(
357
+ type_=typing.Optional[typing.Any], # type: ignore
358
+ object_=_response.json(),
359
+ ),
360
+ ),
361
+ )
362
+ if _response.status_code == 500:
363
+ raise InternalServerError(
364
+ headers=dict(_response.headers),
365
+ body=typing.cast(
366
+ ActualErrorResponse,
367
+ parse_obj_as(
368
+ type_=ActualErrorResponse, # type: ignore
369
+ object_=_response.json(),
370
+ ),
371
+ ),
372
+ )
373
+ if _response.status_code == 503:
374
+ raise ServiceUnavailableError(
375
+ headers=dict(_response.headers),
376
+ body=typing.cast(
377
+ ActualErrorResponse,
378
+ parse_obj_as(
379
+ type_=ActualErrorResponse, # type: ignore
380
+ object_=_response.json(),
381
+ ),
382
+ ),
383
+ )
384
+ _response_json = _response.json()
385
+ except JSONDecodeError:
386
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
387
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
388
+
389
+ def full_text_search(
390
+ self,
391
+ *,
392
+ query: str,
393
+ tenant_id: str,
394
+ sub_tenant_id: typing.Optional[str] = OMIT,
395
+ operator: typing.Optional[Bm25OperatorType] = OMIT,
396
+ max_chunks: typing.Optional[int] = OMIT,
397
+ request_options: typing.Optional[RequestOptions] = None,
398
+ ) -> HttpResponse[FullTextSearchData]:
399
+ """
400
+ Full text search endpoint for Cortex customers.
401
+ Performs full text search with configurable operators for precise text matching against the Findr backend.
402
+
403
+ This endpoint performs a full text search query against the Findr backend, allowing users to retrieve
404
+ relevant content chunks from their indexed documents and sources using BM25-based text matching.
405
+ The search can be customized with various operators to control the matching behavior.
406
+
407
+ Args:
408
+ request (FullTextSearchRequest): The full text search request containing:
409
+ - query (str): Search query string to find relevant content
410
+ - tenant_id (str): Tenant identifier for multi-tenancy
411
+ - sub_tenant_id (str, optional): Sub-tenant identifier, defaults to tenant_id
412
+ - operator (BM25OperatorType, optional): Full text search operator type (OR or AND). Defaults to OR
413
+ - max_chunks (int, optional): Maximum number of content chunks to return (1-1001, defaults to 25)
414
+ api_details (dict): Authentication details obtained from API key validation
415
+
416
+ Returns:
417
+ FullTextSearchData: Success response with full text search results
418
+
419
+ Parameters
420
+ ----------
421
+ query : str
422
+
423
+ tenant_id : str
424
+
425
+ sub_tenant_id : typing.Optional[str]
426
+
427
+ operator : typing.Optional[Bm25OperatorType]
428
+
429
+ max_chunks : typing.Optional[int]
430
+
431
+ request_options : typing.Optional[RequestOptions]
432
+ Request-specific configuration.
433
+
434
+ Returns
435
+ -------
436
+ HttpResponse[FullTextSearchData]
437
+ Successful Response
438
+ """
439
+ _response = self._client_wrapper.httpx_client.request(
440
+ "search/full-text-search",
441
+ method="POST",
442
+ json={
443
+ "query": query,
444
+ "tenant_id": tenant_id,
445
+ "sub_tenant_id": sub_tenant_id,
446
+ "operator": operator,
447
+ "max_chunks": max_chunks,
448
+ },
449
+ headers={
450
+ "content-type": "application/json",
451
+ },
452
+ request_options=request_options,
453
+ omit=OMIT,
454
+ )
455
+ try:
456
+ if 200 <= _response.status_code < 300:
457
+ _data = typing.cast(
458
+ FullTextSearchData,
459
+ parse_obj_as(
460
+ type_=FullTextSearchData, # type: ignore
461
+ object_=_response.json(),
462
+ ),
463
+ )
464
+ return HttpResponse(response=_response, data=_data)
465
+ if _response.status_code == 400:
466
+ raise BadRequestError(
467
+ headers=dict(_response.headers),
468
+ body=typing.cast(
469
+ ActualErrorResponse,
470
+ parse_obj_as(
471
+ type_=ActualErrorResponse, # type: ignore
472
+ object_=_response.json(),
473
+ ),
474
+ ),
475
+ )
476
+ if _response.status_code == 401:
477
+ raise UnauthorizedError(
478
+ headers=dict(_response.headers),
479
+ body=typing.cast(
480
+ ActualErrorResponse,
481
+ parse_obj_as(
482
+ type_=ActualErrorResponse, # type: ignore
483
+ object_=_response.json(),
484
+ ),
485
+ ),
486
+ )
487
+ if _response.status_code == 403:
488
+ raise ForbiddenError(
489
+ headers=dict(_response.headers),
490
+ body=typing.cast(
491
+ ActualErrorResponse,
492
+ parse_obj_as(
493
+ type_=ActualErrorResponse, # type: ignore
494
+ object_=_response.json(),
495
+ ),
496
+ ),
497
+ )
498
+ if _response.status_code == 404:
499
+ raise NotFoundError(
500
+ headers=dict(_response.headers),
501
+ body=typing.cast(
502
+ ActualErrorResponse,
503
+ parse_obj_as(
504
+ type_=ActualErrorResponse, # type: ignore
505
+ object_=_response.json(),
506
+ ),
507
+ ),
508
+ )
509
+ if _response.status_code == 422:
510
+ raise UnprocessableEntityError(
511
+ headers=dict(_response.headers),
512
+ body=typing.cast(
513
+ typing.Optional[typing.Any],
514
+ parse_obj_as(
515
+ type_=typing.Optional[typing.Any], # type: ignore
516
+ object_=_response.json(),
517
+ ),
518
+ ),
519
+ )
520
+ if _response.status_code == 500:
521
+ raise InternalServerError(
522
+ headers=dict(_response.headers),
523
+ body=typing.cast(
524
+ ActualErrorResponse,
525
+ parse_obj_as(
526
+ type_=ActualErrorResponse, # type: ignore
527
+ object_=_response.json(),
528
+ ),
529
+ ),
530
+ )
531
+ if _response.status_code == 503:
532
+ raise ServiceUnavailableError(
533
+ headers=dict(_response.headers),
534
+ body=typing.cast(
535
+ ActualErrorResponse,
536
+ parse_obj_as(
537
+ type_=ActualErrorResponse, # type: ignore
538
+ object_=_response.json(),
539
+ ),
540
+ ),
541
+ )
542
+ _response_json = _response.json()
543
+ except JSONDecodeError:
544
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
545
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
546
+
547
+
548
+ class AsyncRawSearchClient:
549
+ def __init__(self, *, client_wrapper: AsyncClientWrapper):
550
+ self._client_wrapper = client_wrapper
551
+
552
+ async def qna(
553
+ self,
554
+ *,
555
+ question: str,
556
+ session_id: str,
557
+ tenant_id: str,
558
+ context_list: typing.Optional[typing.Sequence[str]] = OMIT,
559
+ search_modes: typing.Optional[typing.Sequence[str]] = OMIT,
560
+ sub_tenant_id: typing.Optional[str] = OMIT,
561
+ highlight_chunks: typing.Optional[bool] = OMIT,
562
+ stream: typing.Optional[bool] = OMIT,
563
+ search_alpha: typing.Optional[float] = OMIT,
564
+ recency_bias: typing.Optional[float] = OMIT,
565
+ ai_generation: typing.Optional[bool] = OMIT,
566
+ top_n: typing.Optional[int] = OMIT,
567
+ user_name: typing.Optional[str] = OMIT,
568
+ user_instructions: typing.Optional[str] = OMIT,
569
+ multi_step_reasoning: typing.Optional[bool] = OMIT,
570
+ auto_agent_routing: typing.Optional[bool] = OMIT,
571
+ metadata: typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]] = OMIT,
572
+ request_options: typing.Optional[RequestOptions] = None,
573
+ ) -> AsyncHttpResponse[typing.Optional[typing.Any]]:
574
+ """
575
+ Parameters
576
+ ----------
577
+ question : str
578
+
579
+ session_id : str
580
+
581
+ tenant_id : str
582
+
583
+ context_list : typing.Optional[typing.Sequence[str]]
584
+
585
+ search_modes : typing.Optional[typing.Sequence[str]]
586
+
587
+ sub_tenant_id : typing.Optional[str]
588
+
589
+ highlight_chunks : typing.Optional[bool]
590
+
591
+ stream : typing.Optional[bool]
592
+
593
+ search_alpha : typing.Optional[float]
594
+
595
+ recency_bias : typing.Optional[float]
596
+
597
+ ai_generation : typing.Optional[bool]
598
+
599
+ top_n : typing.Optional[int]
600
+
601
+ user_name : typing.Optional[str]
602
+
603
+ user_instructions : typing.Optional[str]
604
+
605
+ multi_step_reasoning : typing.Optional[bool]
606
+
607
+ auto_agent_routing : typing.Optional[bool]
608
+
609
+ metadata : typing.Optional[typing.Dict[str, typing.Optional[typing.Any]]]
610
+
611
+ request_options : typing.Optional[RequestOptions]
612
+ Request-specific configuration.
613
+
614
+ Returns
615
+ -------
616
+ AsyncHttpResponse[typing.Optional[typing.Any]]
617
+ Successful Response
618
+ """
619
+ _response = await self._client_wrapper.httpx_client.request(
620
+ "search/qna",
621
+ method="POST",
622
+ json={
623
+ "question": question,
624
+ "session_id": session_id,
625
+ "tenant_id": tenant_id,
626
+ "context_list": context_list,
627
+ "search_modes": search_modes,
628
+ "sub_tenant_id": sub_tenant_id,
629
+ "highlight_chunks": highlight_chunks,
630
+ "stream": stream,
631
+ "search_alpha": search_alpha,
632
+ "recency_bias": recency_bias,
633
+ "ai_generation": ai_generation,
634
+ "top_n": top_n,
635
+ "user_name": user_name,
636
+ "user_instructions": user_instructions,
637
+ "multi_step_reasoning": multi_step_reasoning,
638
+ "auto_agent_routing": auto_agent_routing,
639
+ "metadata": metadata,
640
+ },
641
+ headers={
642
+ "content-type": "application/json",
643
+ },
644
+ request_options=request_options,
645
+ omit=OMIT,
646
+ )
647
+ try:
648
+ if _response is None or not _response.text.strip():
649
+ return AsyncHttpResponse(response=_response, data=None)
650
+ if 200 <= _response.status_code < 300:
651
+ _data = typing.cast(
652
+ typing.Optional[typing.Any],
653
+ parse_obj_as(
654
+ type_=typing.Optional[typing.Any], # type: ignore
655
+ object_=_response.json(),
656
+ ),
657
+ )
658
+ return AsyncHttpResponse(response=_response, data=_data)
659
+ if _response.status_code == 400:
660
+ raise BadRequestError(
661
+ headers=dict(_response.headers),
662
+ body=typing.cast(
663
+ ActualErrorResponse,
664
+ parse_obj_as(
665
+ type_=ActualErrorResponse, # type: ignore
666
+ object_=_response.json(),
667
+ ),
668
+ ),
669
+ )
670
+ if _response.status_code == 401:
671
+ raise UnauthorizedError(
672
+ headers=dict(_response.headers),
673
+ body=typing.cast(
674
+ ActualErrorResponse,
675
+ parse_obj_as(
676
+ type_=ActualErrorResponse, # type: ignore
677
+ object_=_response.json(),
678
+ ),
679
+ ),
680
+ )
681
+ if _response.status_code == 403:
682
+ raise ForbiddenError(
683
+ headers=dict(_response.headers),
684
+ body=typing.cast(
685
+ ActualErrorResponse,
686
+ parse_obj_as(
687
+ type_=ActualErrorResponse, # type: ignore
688
+ object_=_response.json(),
689
+ ),
690
+ ),
691
+ )
692
+ if _response.status_code == 404:
693
+ raise NotFoundError(
694
+ headers=dict(_response.headers),
695
+ body=typing.cast(
696
+ ActualErrorResponse,
697
+ parse_obj_as(
698
+ type_=ActualErrorResponse, # type: ignore
699
+ object_=_response.json(),
700
+ ),
701
+ ),
702
+ )
703
+ if _response.status_code == 422:
704
+ raise UnprocessableEntityError(
705
+ headers=dict(_response.headers),
706
+ body=typing.cast(
707
+ typing.Optional[typing.Any],
708
+ parse_obj_as(
709
+ type_=typing.Optional[typing.Any], # type: ignore
710
+ object_=_response.json(),
711
+ ),
712
+ ),
713
+ )
714
+ if _response.status_code == 500:
715
+ raise InternalServerError(
716
+ headers=dict(_response.headers),
717
+ body=typing.cast(
718
+ ActualErrorResponse,
719
+ parse_obj_as(
720
+ type_=ActualErrorResponse, # type: ignore
721
+ object_=_response.json(),
722
+ ),
723
+ ),
724
+ )
725
+ if _response.status_code == 503:
726
+ raise ServiceUnavailableError(
727
+ headers=dict(_response.headers),
728
+ body=typing.cast(
729
+ ActualErrorResponse,
730
+ parse_obj_as(
731
+ type_=ActualErrorResponse, # type: ignore
732
+ object_=_response.json(),
733
+ ),
734
+ ),
735
+ )
736
+ _response_json = _response.json()
737
+ except JSONDecodeError:
738
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
739
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
740
+
741
+ async def retrieve(
742
+ self,
743
+ *,
744
+ query: str,
745
+ tenant_id: str,
746
+ sub_tenant_id: typing.Optional[str] = OMIT,
747
+ max_chunks: typing.Optional[int] = OMIT,
748
+ alpha: typing.Optional[Alpha] = OMIT,
749
+ recency_bias: typing.Optional[float] = OMIT,
750
+ num_related_chunks: typing.Optional[int] = OMIT,
751
+ request_options: typing.Optional[RequestOptions] = None,
752
+ ) -> AsyncHttpResponse[SearchData]:
753
+ """
754
+ Search for content within indexed sources using semantic and keyword search capabilities.
755
+
756
+ This endpoint performs a search query against the Findr backend, allowing users to retrieve
757
+ relevant content chunks from their indexed documents and sources. The search can be customized
758
+ with various parameters to control the number of results and search behavior.
759
+
760
+ Args:
761
+ request (SearchRequest): The search request containing:
762
+ - query (str): Search query string to find relevant content
763
+ - tenant_id (str, optional): Tenant identifier for multi-tenancy
764
+ - sub_tenant_id (str, optional): Sub-tenant identifier, defaults to tenant_id
765
+ - max_chunks (int, optional): Maximum number of content chunks to return
766
+ - alpha (Union[float, str], optional): Search algorithm parameter for result ranking (default: 0.8). Can be float-type (0.0-1.0) or 'auto' for dynamic selection
767
+ - recency_bias (float, optional): Bias towards more recent content (default: 0.5)
768
+ - num_related_chunks (int, optional): Number of related chunks to return (default: 0)
769
+ api_details (dict): Authentication details obtained from API key validation
770
+
771
+ Returns:
772
+ SearchData: Success response with search results
773
+
774
+ Parameters
775
+ ----------
776
+ query : str
777
+
778
+ tenant_id : str
779
+
780
+ sub_tenant_id : typing.Optional[str]
781
+
782
+ max_chunks : typing.Optional[int]
783
+
784
+ alpha : typing.Optional[Alpha]
785
+
786
+ recency_bias : typing.Optional[float]
787
+
788
+ num_related_chunks : typing.Optional[int]
789
+
790
+ request_options : typing.Optional[RequestOptions]
791
+ Request-specific configuration.
792
+
793
+ Returns
794
+ -------
795
+ AsyncHttpResponse[SearchData]
796
+ Successful Response
797
+ """
798
+ _response = await self._client_wrapper.httpx_client.request(
799
+ "search/retrieve",
800
+ method="POST",
801
+ json={
802
+ "query": query,
803
+ "tenant_id": tenant_id,
804
+ "sub_tenant_id": sub_tenant_id,
805
+ "max_chunks": max_chunks,
806
+ "alpha": convert_and_respect_annotation_metadata(object_=alpha, annotation=Alpha, direction="write"),
807
+ "recency_bias": recency_bias,
808
+ "num_related_chunks": num_related_chunks,
809
+ },
810
+ headers={
811
+ "content-type": "application/json",
812
+ },
813
+ request_options=request_options,
814
+ omit=OMIT,
815
+ )
816
+ try:
817
+ if 200 <= _response.status_code < 300:
818
+ _data = typing.cast(
819
+ SearchData,
820
+ parse_obj_as(
821
+ type_=SearchData, # type: ignore
822
+ object_=_response.json(),
823
+ ),
824
+ )
825
+ return AsyncHttpResponse(response=_response, data=_data)
826
+ if _response.status_code == 400:
827
+ raise BadRequestError(
828
+ headers=dict(_response.headers),
829
+ body=typing.cast(
830
+ ActualErrorResponse,
831
+ parse_obj_as(
832
+ type_=ActualErrorResponse, # type: ignore
833
+ object_=_response.json(),
834
+ ),
835
+ ),
836
+ )
837
+ if _response.status_code == 401:
838
+ raise UnauthorizedError(
839
+ headers=dict(_response.headers),
840
+ body=typing.cast(
841
+ ActualErrorResponse,
842
+ parse_obj_as(
843
+ type_=ActualErrorResponse, # type: ignore
844
+ object_=_response.json(),
845
+ ),
846
+ ),
847
+ )
848
+ if _response.status_code == 403:
849
+ raise ForbiddenError(
850
+ headers=dict(_response.headers),
851
+ body=typing.cast(
852
+ ActualErrorResponse,
853
+ parse_obj_as(
854
+ type_=ActualErrorResponse, # type: ignore
855
+ object_=_response.json(),
856
+ ),
857
+ ),
858
+ )
859
+ if _response.status_code == 404:
860
+ raise NotFoundError(
861
+ headers=dict(_response.headers),
862
+ body=typing.cast(
863
+ ActualErrorResponse,
864
+ parse_obj_as(
865
+ type_=ActualErrorResponse, # type: ignore
866
+ object_=_response.json(),
867
+ ),
868
+ ),
869
+ )
870
+ if _response.status_code == 422:
871
+ raise UnprocessableEntityError(
872
+ headers=dict(_response.headers),
873
+ body=typing.cast(
874
+ typing.Optional[typing.Any],
875
+ parse_obj_as(
876
+ type_=typing.Optional[typing.Any], # type: ignore
877
+ object_=_response.json(),
878
+ ),
879
+ ),
880
+ )
881
+ if _response.status_code == 500:
882
+ raise InternalServerError(
883
+ headers=dict(_response.headers),
884
+ body=typing.cast(
885
+ ActualErrorResponse,
886
+ parse_obj_as(
887
+ type_=ActualErrorResponse, # type: ignore
888
+ object_=_response.json(),
889
+ ),
890
+ ),
891
+ )
892
+ if _response.status_code == 503:
893
+ raise ServiceUnavailableError(
894
+ headers=dict(_response.headers),
895
+ body=typing.cast(
896
+ ActualErrorResponse,
897
+ parse_obj_as(
898
+ type_=ActualErrorResponse, # type: ignore
899
+ object_=_response.json(),
900
+ ),
901
+ ),
902
+ )
903
+ _response_json = _response.json()
904
+ except JSONDecodeError:
905
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
906
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
907
+
908
+ async def full_text_search(
909
+ self,
910
+ *,
911
+ query: str,
912
+ tenant_id: str,
913
+ sub_tenant_id: typing.Optional[str] = OMIT,
914
+ operator: typing.Optional[Bm25OperatorType] = OMIT,
915
+ max_chunks: typing.Optional[int] = OMIT,
916
+ request_options: typing.Optional[RequestOptions] = None,
917
+ ) -> AsyncHttpResponse[FullTextSearchData]:
918
+ """
919
+ Full text search endpoint for Cortex customers.
920
+ Performs full text search with configurable operators for precise text matching against the Findr backend.
921
+
922
+ This endpoint performs a full text search query against the Findr backend, allowing users to retrieve
923
+ relevant content chunks from their indexed documents and sources using BM25-based text matching.
924
+ The search can be customized with various operators to control the matching behavior.
925
+
926
+ Args:
927
+ request (FullTextSearchRequest): The full text search request containing:
928
+ - query (str): Search query string to find relevant content
929
+ - tenant_id (str): Tenant identifier for multi-tenancy
930
+ - sub_tenant_id (str, optional): Sub-tenant identifier, defaults to tenant_id
931
+ - operator (BM25OperatorType, optional): Full text search operator type (OR or AND). Defaults to OR
932
+ - max_chunks (int, optional): Maximum number of content chunks to return (1-1001, defaults to 25)
933
+ api_details (dict): Authentication details obtained from API key validation
934
+
935
+ Returns:
936
+ FullTextSearchData: Success response with full text search results
937
+
938
+ Parameters
939
+ ----------
940
+ query : str
941
+
942
+ tenant_id : str
943
+
944
+ sub_tenant_id : typing.Optional[str]
945
+
946
+ operator : typing.Optional[Bm25OperatorType]
947
+
948
+ max_chunks : typing.Optional[int]
949
+
950
+ request_options : typing.Optional[RequestOptions]
951
+ Request-specific configuration.
952
+
953
+ Returns
954
+ -------
955
+ AsyncHttpResponse[FullTextSearchData]
956
+ Successful Response
957
+ """
958
+ _response = await self._client_wrapper.httpx_client.request(
959
+ "search/full-text-search",
960
+ method="POST",
961
+ json={
962
+ "query": query,
963
+ "tenant_id": tenant_id,
964
+ "sub_tenant_id": sub_tenant_id,
965
+ "operator": operator,
966
+ "max_chunks": max_chunks,
967
+ },
968
+ headers={
969
+ "content-type": "application/json",
970
+ },
971
+ request_options=request_options,
972
+ omit=OMIT,
973
+ )
974
+ try:
975
+ if 200 <= _response.status_code < 300:
976
+ _data = typing.cast(
977
+ FullTextSearchData,
978
+ parse_obj_as(
979
+ type_=FullTextSearchData, # type: ignore
980
+ object_=_response.json(),
981
+ ),
982
+ )
983
+ return AsyncHttpResponse(response=_response, data=_data)
984
+ if _response.status_code == 400:
985
+ raise BadRequestError(
986
+ headers=dict(_response.headers),
987
+ body=typing.cast(
988
+ ActualErrorResponse,
989
+ parse_obj_as(
990
+ type_=ActualErrorResponse, # type: ignore
991
+ object_=_response.json(),
992
+ ),
993
+ ),
994
+ )
995
+ if _response.status_code == 401:
996
+ raise UnauthorizedError(
997
+ headers=dict(_response.headers),
998
+ body=typing.cast(
999
+ ActualErrorResponse,
1000
+ parse_obj_as(
1001
+ type_=ActualErrorResponse, # type: ignore
1002
+ object_=_response.json(),
1003
+ ),
1004
+ ),
1005
+ )
1006
+ if _response.status_code == 403:
1007
+ raise ForbiddenError(
1008
+ headers=dict(_response.headers),
1009
+ body=typing.cast(
1010
+ ActualErrorResponse,
1011
+ parse_obj_as(
1012
+ type_=ActualErrorResponse, # type: ignore
1013
+ object_=_response.json(),
1014
+ ),
1015
+ ),
1016
+ )
1017
+ if _response.status_code == 404:
1018
+ raise NotFoundError(
1019
+ headers=dict(_response.headers),
1020
+ body=typing.cast(
1021
+ ActualErrorResponse,
1022
+ parse_obj_as(
1023
+ type_=ActualErrorResponse, # type: ignore
1024
+ object_=_response.json(),
1025
+ ),
1026
+ ),
1027
+ )
1028
+ if _response.status_code == 422:
1029
+ raise UnprocessableEntityError(
1030
+ headers=dict(_response.headers),
1031
+ body=typing.cast(
1032
+ typing.Optional[typing.Any],
1033
+ parse_obj_as(
1034
+ type_=typing.Optional[typing.Any], # type: ignore
1035
+ object_=_response.json(),
1036
+ ),
1037
+ ),
1038
+ )
1039
+ if _response.status_code == 500:
1040
+ raise InternalServerError(
1041
+ headers=dict(_response.headers),
1042
+ body=typing.cast(
1043
+ ActualErrorResponse,
1044
+ parse_obj_as(
1045
+ type_=ActualErrorResponse, # type: ignore
1046
+ object_=_response.json(),
1047
+ ),
1048
+ ),
1049
+ )
1050
+ if _response.status_code == 503:
1051
+ raise ServiceUnavailableError(
1052
+ headers=dict(_response.headers),
1053
+ body=typing.cast(
1054
+ ActualErrorResponse,
1055
+ parse_obj_as(
1056
+ type_=ActualErrorResponse, # type: ignore
1057
+ object_=_response.json(),
1058
+ ),
1059
+ ),
1060
+ )
1061
+ _response_json = _response.json()
1062
+ except JSONDecodeError:
1063
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
1064
+ raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)