unique_toolkit 0.7.7__py3-none-any.whl → 1.23.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.

Potentially problematic release.


This version of unique_toolkit might be problematic. Click here for more details.

Files changed (166) hide show
  1. unique_toolkit/__init__.py +28 -1
  2. unique_toolkit/_common/api_calling/human_verification_manager.py +343 -0
  3. unique_toolkit/_common/base_model_type_attribute.py +303 -0
  4. unique_toolkit/_common/chunk_relevancy_sorter/config.py +49 -0
  5. unique_toolkit/_common/chunk_relevancy_sorter/exception.py +5 -0
  6. unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +46 -0
  7. unique_toolkit/_common/chunk_relevancy_sorter/service.py +374 -0
  8. unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +275 -0
  9. unique_toolkit/_common/default_language_model.py +12 -0
  10. unique_toolkit/_common/docx_generator/__init__.py +7 -0
  11. unique_toolkit/_common/docx_generator/config.py +12 -0
  12. unique_toolkit/_common/docx_generator/schemas.py +80 -0
  13. unique_toolkit/_common/docx_generator/service.py +252 -0
  14. unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  15. unique_toolkit/_common/endpoint_builder.py +305 -0
  16. unique_toolkit/_common/endpoint_requestor.py +430 -0
  17. unique_toolkit/_common/exception.py +24 -0
  18. unique_toolkit/_common/feature_flags/schema.py +9 -0
  19. unique_toolkit/_common/pydantic/rjsf_tags.py +936 -0
  20. unique_toolkit/_common/pydantic_helpers.py +154 -0
  21. unique_toolkit/_common/referencing.py +53 -0
  22. unique_toolkit/_common/string_utilities.py +140 -0
  23. unique_toolkit/_common/tests/test_referencing.py +521 -0
  24. unique_toolkit/_common/tests/test_string_utilities.py +506 -0
  25. unique_toolkit/_common/token/image_token_counting.py +67 -0
  26. unique_toolkit/_common/token/token_counting.py +204 -0
  27. unique_toolkit/_common/utils/__init__.py +1 -0
  28. unique_toolkit/_common/utils/files.py +43 -0
  29. unique_toolkit/_common/utils/structured_output/__init__.py +1 -0
  30. unique_toolkit/_common/utils/structured_output/schema.py +5 -0
  31. unique_toolkit/_common/utils/write_configuration.py +51 -0
  32. unique_toolkit/_common/validators.py +101 -4
  33. unique_toolkit/agentic/__init__.py +1 -0
  34. unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +28 -0
  35. unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +278 -0
  36. unique_toolkit/agentic/evaluation/config.py +36 -0
  37. unique_toolkit/{evaluators → agentic/evaluation}/context_relevancy/prompts.py +25 -0
  38. unique_toolkit/agentic/evaluation/context_relevancy/schema.py +80 -0
  39. unique_toolkit/agentic/evaluation/context_relevancy/service.py +273 -0
  40. unique_toolkit/agentic/evaluation/evaluation_manager.py +218 -0
  41. unique_toolkit/agentic/evaluation/hallucination/constants.py +61 -0
  42. unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +111 -0
  43. unique_toolkit/{evaluators → agentic/evaluation}/hallucination/prompts.py +1 -1
  44. unique_toolkit/{evaluators → agentic/evaluation}/hallucination/service.py +16 -15
  45. unique_toolkit/{evaluators → agentic/evaluation}/hallucination/utils.py +30 -20
  46. unique_toolkit/{evaluators → agentic/evaluation}/output_parser.py +20 -2
  47. unique_toolkit/{evaluators → agentic/evaluation}/schemas.py +27 -7
  48. unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +253 -0
  49. unique_toolkit/agentic/evaluation/tests/test_output_parser.py +87 -0
  50. unique_toolkit/agentic/history_manager/history_construction_with_contents.py +297 -0
  51. unique_toolkit/agentic/history_manager/history_manager.py +242 -0
  52. unique_toolkit/agentic/history_manager/loop_token_reducer.py +484 -0
  53. unique_toolkit/agentic/history_manager/utils.py +96 -0
  54. unique_toolkit/agentic/postprocessor/postprocessor_manager.py +212 -0
  55. unique_toolkit/agentic/reference_manager/reference_manager.py +103 -0
  56. unique_toolkit/agentic/responses_api/__init__.py +19 -0
  57. unique_toolkit/agentic/responses_api/postprocessors/code_display.py +63 -0
  58. unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +145 -0
  59. unique_toolkit/agentic/responses_api/stream_handler.py +15 -0
  60. unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +141 -0
  61. unique_toolkit/agentic/thinking_manager/thinking_manager.py +103 -0
  62. unique_toolkit/agentic/tools/__init__.py +1 -0
  63. unique_toolkit/agentic/tools/a2a/__init__.py +36 -0
  64. unique_toolkit/agentic/tools/a2a/config.py +17 -0
  65. unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +15 -0
  66. unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +66 -0
  67. unique_toolkit/agentic/tools/a2a/evaluation/config.py +55 -0
  68. unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +260 -0
  69. unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +9 -0
  70. unique_toolkit/agentic/tools/a2a/manager.py +55 -0
  71. unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +21 -0
  72. unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +185 -0
  73. unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +73 -0
  74. unique_toolkit/agentic/tools/a2a/postprocessing/config.py +45 -0
  75. unique_toolkit/agentic/tools/a2a/postprocessing/display.py +180 -0
  76. unique_toolkit/agentic/tools/a2a/postprocessing/references.py +101 -0
  77. unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +1335 -0
  78. unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +603 -0
  79. unique_toolkit/agentic/tools/a2a/prompts.py +46 -0
  80. unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +6 -0
  81. unique_toolkit/agentic/tools/a2a/response_watcher/service.py +91 -0
  82. unique_toolkit/agentic/tools/a2a/tool/__init__.py +4 -0
  83. unique_toolkit/agentic/tools/a2a/tool/_memory.py +26 -0
  84. unique_toolkit/agentic/tools/a2a/tool/_schema.py +9 -0
  85. unique_toolkit/agentic/tools/a2a/tool/config.py +73 -0
  86. unique_toolkit/agentic/tools/a2a/tool/service.py +306 -0
  87. unique_toolkit/agentic/tools/agent_chunks_hanlder.py +65 -0
  88. unique_toolkit/agentic/tools/config.py +167 -0
  89. unique_toolkit/agentic/tools/factory.py +44 -0
  90. unique_toolkit/agentic/tools/mcp/__init__.py +4 -0
  91. unique_toolkit/agentic/tools/mcp/manager.py +71 -0
  92. unique_toolkit/agentic/tools/mcp/models.py +28 -0
  93. unique_toolkit/agentic/tools/mcp/tool_wrapper.py +234 -0
  94. unique_toolkit/agentic/tools/openai_builtin/__init__.py +11 -0
  95. unique_toolkit/agentic/tools/openai_builtin/base.py +30 -0
  96. unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +8 -0
  97. unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +57 -0
  98. unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +230 -0
  99. unique_toolkit/agentic/tools/openai_builtin/manager.py +62 -0
  100. unique_toolkit/agentic/tools/schemas.py +141 -0
  101. unique_toolkit/agentic/tools/test/test_mcp_manager.py +536 -0
  102. unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +445 -0
  103. unique_toolkit/agentic/tools/tool.py +183 -0
  104. unique_toolkit/agentic/tools/tool_manager.py +523 -0
  105. unique_toolkit/agentic/tools/tool_progress_reporter.py +285 -0
  106. unique_toolkit/agentic/tools/utils/__init__.py +19 -0
  107. unique_toolkit/agentic/tools/utils/execution/__init__.py +1 -0
  108. unique_toolkit/agentic/tools/utils/execution/execution.py +286 -0
  109. unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  110. unique_toolkit/agentic/tools/utils/source_handling/schema.py +21 -0
  111. unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +207 -0
  112. unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +216 -0
  113. unique_toolkit/app/__init__.py +6 -0
  114. unique_toolkit/app/dev_util.py +180 -0
  115. unique_toolkit/app/init_sdk.py +32 -1
  116. unique_toolkit/app/schemas.py +198 -31
  117. unique_toolkit/app/unique_settings.py +367 -0
  118. unique_toolkit/chat/__init__.py +8 -1
  119. unique_toolkit/chat/deprecated/service.py +232 -0
  120. unique_toolkit/chat/functions.py +642 -77
  121. unique_toolkit/chat/rendering.py +34 -0
  122. unique_toolkit/chat/responses_api.py +461 -0
  123. unique_toolkit/chat/schemas.py +133 -2
  124. unique_toolkit/chat/service.py +115 -767
  125. unique_toolkit/content/functions.py +153 -4
  126. unique_toolkit/content/schemas.py +122 -15
  127. unique_toolkit/content/service.py +278 -44
  128. unique_toolkit/content/smart_rules.py +301 -0
  129. unique_toolkit/content/utils.py +8 -3
  130. unique_toolkit/embedding/service.py +102 -11
  131. unique_toolkit/framework_utilities/__init__.py +1 -0
  132. unique_toolkit/framework_utilities/langchain/client.py +71 -0
  133. unique_toolkit/framework_utilities/langchain/history.py +19 -0
  134. unique_toolkit/framework_utilities/openai/__init__.py +6 -0
  135. unique_toolkit/framework_utilities/openai/client.py +83 -0
  136. unique_toolkit/framework_utilities/openai/message_builder.py +229 -0
  137. unique_toolkit/framework_utilities/utils.py +23 -0
  138. unique_toolkit/language_model/__init__.py +3 -0
  139. unique_toolkit/language_model/builder.py +27 -11
  140. unique_toolkit/language_model/default_language_model.py +3 -0
  141. unique_toolkit/language_model/functions.py +327 -43
  142. unique_toolkit/language_model/infos.py +992 -50
  143. unique_toolkit/language_model/reference.py +242 -0
  144. unique_toolkit/language_model/schemas.py +475 -48
  145. unique_toolkit/language_model/service.py +228 -27
  146. unique_toolkit/protocols/support.py +145 -0
  147. unique_toolkit/services/__init__.py +7 -0
  148. unique_toolkit/services/chat_service.py +1630 -0
  149. unique_toolkit/services/knowledge_base.py +861 -0
  150. unique_toolkit/short_term_memory/service.py +178 -41
  151. unique_toolkit/smart_rules/__init__.py +0 -0
  152. unique_toolkit/smart_rules/compile.py +56 -0
  153. unique_toolkit/test_utilities/events.py +197 -0
  154. {unique_toolkit-0.7.7.dist-info → unique_toolkit-1.23.0.dist-info}/METADATA +606 -7
  155. unique_toolkit-1.23.0.dist-info/RECORD +182 -0
  156. unique_toolkit/evaluators/__init__.py +0 -1
  157. unique_toolkit/evaluators/config.py +0 -35
  158. unique_toolkit/evaluators/constants.py +0 -1
  159. unique_toolkit/evaluators/context_relevancy/constants.py +0 -32
  160. unique_toolkit/evaluators/context_relevancy/service.py +0 -53
  161. unique_toolkit/evaluators/context_relevancy/utils.py +0 -142
  162. unique_toolkit/evaluators/hallucination/constants.py +0 -41
  163. unique_toolkit-0.7.7.dist-info/RECORD +0 -64
  164. /unique_toolkit/{evaluators → agentic/evaluation}/exception.py +0 -0
  165. {unique_toolkit-0.7.7.dist-info → unique_toolkit-1.23.0.dist-info}/LICENSE +0 -0
  166. {unique_toolkit-0.7.7.dist-info → unique_toolkit-1.23.0.dist-info}/WHEEL +0 -0
@@ -3,6 +3,7 @@ import os
3
3
  import re
4
4
  import tempfile
5
5
  from pathlib import Path
6
+ from typing import Any
6
7
 
7
8
  import requests
8
9
  import unique_sdk
@@ -12,8 +13,12 @@ from unique_toolkit.content.constants import DEFAULT_SEARCH_LANGUAGE
12
13
  from unique_toolkit.content.schemas import (
13
14
  Content,
14
15
  ContentChunk,
16
+ ContentInfo,
15
17
  ContentRerankerConfig,
16
18
  ContentSearchType,
19
+ DeleteContentResponse,
20
+ FolderInfo,
21
+ PaginatedContentInfos,
17
22
  )
18
23
  from unique_toolkit.content.utils import map_contents, map_to_content_chunks
19
24
 
@@ -33,6 +38,7 @@ def search_content_chunks(
33
38
  chat_only: bool | None = None,
34
39
  metadata_filter: dict | None = None,
35
40
  content_ids: list[str] | None = None,
41
+ score_threshold: float | None = None,
36
42
  ) -> list[ContentChunk]:
37
43
  """
38
44
  Performs a synchronous search for content chunks in the knowledge base.
@@ -47,6 +53,7 @@ def search_content_chunks(
47
53
  chat_only (bool | None): Whether to search only in the current chat. Defaults to None.
48
54
  metadata_filter (dict | None): UniqueQL metadata filter. If unspecified/None, it tries to use the metadata filter from the event. Defaults to None.
49
55
  content_ids (list[str] | None): The content IDs to search. Defaults to None.
56
+ score_threshold (float | None): The minimum score threshold for results. Defaults to 0.
50
57
  Returns:
51
58
  list[ContentChunk]: The search results.
52
59
  """
@@ -72,6 +79,7 @@ def search_content_chunks(
72
79
  chatOnly=chat_only,
73
80
  metaDataFilter=metadata_filter,
74
81
  contentIds=content_ids,
82
+ scoreThreshold=score_threshold,
75
83
  )
76
84
  return map_to_content_chunks(searches)
77
85
  except Exception as e:
@@ -92,6 +100,7 @@ async def search_content_chunks_async(
92
100
  chat_only: bool | None = None,
93
101
  metadata_filter: dict | None = None,
94
102
  content_ids: list[str] | None = None,
103
+ score_threshold: float | None = None,
95
104
  ):
96
105
  """
97
106
  Performs an asynchronous search for content chunks in the knowledge base.
@@ -120,6 +129,7 @@ async def search_content_chunks_async(
120
129
  chatOnly=chat_only,
121
130
  metaDataFilter=metadata_filter,
122
131
  contentIds=content_ids,
132
+ scoreThreshold=score_threshold,
123
133
  )
124
134
  return map_to_content_chunks(searches)
125
135
  except Exception as e:
@@ -213,6 +223,8 @@ def upload_content_from_bytes(
213
223
  scope_id: str | None = None,
214
224
  chat_id: str | None = None,
215
225
  skip_ingestion: bool = False,
226
+ ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
227
+ metadata: dict[str, Any] | None = None,
216
228
  ):
217
229
  """
218
230
  Uploads content to the knowledge base.
@@ -226,6 +238,8 @@ def upload_content_from_bytes(
226
238
  scope_id (str | None): The scope ID. Defaults to None.
227
239
  chat_id (str | None): The chat ID. Defaults to None.
228
240
  skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
241
+ ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
242
+ metadata ( dict[str, Any] | None): The metadata for the content. Defaults to None.
229
243
 
230
244
  Returns:
231
245
  Content: The uploaded content.
@@ -241,6 +255,8 @@ def upload_content_from_bytes(
241
255
  scope_id=scope_id,
242
256
  chat_id=chat_id,
243
257
  skip_ingestion=skip_ingestion,
258
+ ingestion_config=ingestion_config,
259
+ metadata=metadata,
244
260
  )
245
261
  except Exception as e:
246
262
  logger.error(f"Error while uploading content: {e}")
@@ -256,6 +272,9 @@ def upload_content(
256
272
  scope_id: str | None = None,
257
273
  chat_id: str | None = None,
258
274
  skip_ingestion: bool = False,
275
+ skip_excel_ingestion: bool = False,
276
+ ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
277
+ metadata: dict[str, Any] | None = None,
259
278
  ):
260
279
  """
261
280
  Uploads content to the knowledge base.
@@ -269,6 +288,9 @@ def upload_content(
269
288
  scope_id (str | None): The scope ID. Defaults to None.
270
289
  chat_id (str | None): The chat ID. Defaults to None.
271
290
  skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
291
+ skip_excel_ingestion (bool): Whether to skip excel ingestion. Defaults to False.
292
+ ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
293
+ metadata ( dict[str, Any] | None): The metadata for the content. Defaults to None.
272
294
 
273
295
  Returns:
274
296
  Content: The uploaded content.
@@ -284,6 +306,9 @@ def upload_content(
284
306
  scope_id=scope_id,
285
307
  chat_id=chat_id,
286
308
  skip_ingestion=skip_ingestion,
309
+ skip_excel_ingestion=skip_excel_ingestion,
310
+ ingestion_config=ingestion_config,
311
+ metadata=metadata,
287
312
  )
288
313
  except Exception as e:
289
314
  logger.error(f"Error while uploading content: {e}")
@@ -299,6 +324,9 @@ def _trigger_upload_content(
299
324
  scope_id: str | None = None,
300
325
  chat_id: str | None = None,
301
326
  skip_ingestion: bool = False,
327
+ skip_excel_ingestion: bool = False,
328
+ ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
329
+ metadata: dict[str, Any] | None = None,
302
330
  ):
303
331
  """
304
332
  Uploads content to the knowledge base.
@@ -312,6 +340,9 @@ def _trigger_upload_content(
312
340
  scope_id (str | None): The scope ID. Defaults to None.
313
341
  chat_id (str | None): The chat ID. Defaults to None.
314
342
  skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
343
+ skip_excel_ingestion (bool): Whether to skip excel ingestion. Defaults to False.
344
+ ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
345
+ metadata (dict[str, Any] | None): The metadata for the content. Defaults to None.
315
346
 
316
347
  Returns:
317
348
  Content: The uploaded content.
@@ -368,16 +399,23 @@ def _trigger_upload_content(
368
399
  logger.error(error_msg)
369
400
  raise ValueError(error_msg)
370
401
 
402
+ if ingestion_config is None:
403
+ ingestion_config = {}
404
+
405
+ if skip_excel_ingestion:
406
+ ingestion_config["uniqueIngestionMode"] = "SKIP_EXCEL_INGESTION"
407
+ elif skip_ingestion:
408
+ ingestion_config["uniqueIngestionMode"] = "SKIP_INGESTION"
409
+
371
410
  input_dict = {
372
411
  "key": content_name,
373
412
  "title": content_name,
374
413
  "mimeType": mime_type,
375
414
  "byteSize": byte_size,
415
+ "ingestionConfig": ingestion_config,
416
+ "metadata": metadata,
376
417
  }
377
418
 
378
- if skip_ingestion:
379
- input_dict["ingestionConfig"] = {"uniqueIngestionMode": "SKIP_INGESTION"}
380
-
381
419
  if chat_id:
382
420
  _upsert_content(
383
421
  user_id=user_id,
@@ -395,7 +433,7 @@ def _trigger_upload_content(
395
433
  scope_id=scope_id,
396
434
  ) # type: ignore
397
435
 
398
- return Content(**created_content)
436
+ return Content.model_validate(created_content, by_alias=True, by_name=True)
399
437
 
400
438
 
401
439
  def request_content_by_id(
@@ -543,3 +581,114 @@ def download_content(
543
581
  raise Exception(error_msg)
544
582
 
545
583
  return content_path
584
+
585
+
586
+ def get_content_info(
587
+ user_id: str,
588
+ company_id: str,
589
+ *,
590
+ metadata_filter: dict[str, Any] | None = None,
591
+ skip: int | None = None,
592
+ take: int | None = None,
593
+ file_path: str | None = None,
594
+ ):
595
+ """Gets the info of a content."""
596
+
597
+ get_info_params = unique_sdk.Content.ContentInfoParams(
598
+ metadataFilter=metadata_filter or None, # Dict cannot be empty
599
+ )
600
+ if skip:
601
+ get_info_params["skip"] = skip
602
+ if take:
603
+ get_info_params["take"] = take
604
+ if file_path:
605
+ get_info_params["filePath"] = file_path
606
+
607
+ content_info = unique_sdk.Content.get_infos(
608
+ user_id=user_id, company_id=company_id, **get_info_params
609
+ )
610
+ return PaginatedContentInfos.model_validate(
611
+ content_info, by_alias=True, by_name=True
612
+ )
613
+
614
+
615
+ def get_folder_info(user_id: str, company_id: str, *, scope_id: str) -> FolderInfo:
616
+ info = unique_sdk.Folder.get_info(
617
+ user_id=user_id, company_id=company_id, scopeId=scope_id
618
+ )
619
+
620
+ return FolderInfo.model_validate(info, by_alias=True, by_name=True)
621
+
622
+
623
+ def update_content(
624
+ user_id: str,
625
+ company_id: str,
626
+ *,
627
+ content_id: str,
628
+ metadata: dict[str, Any],
629
+ file_path: str | None = None,
630
+ owner_id: str | None = None,
631
+ parent_folder_path: str | None = None,
632
+ title: str | None = None,
633
+ ) -> ContentInfo:
634
+ """Updates the metadata of a content."""
635
+
636
+ update_params = unique_sdk.Content.UpdateParams(
637
+ contentId=content_id, metadata=metadata
638
+ )
639
+
640
+ if file_path:
641
+ update_params["filePath"] = file_path
642
+ if owner_id:
643
+ update_params["ownerId"] = owner_id
644
+ if parent_folder_path:
645
+ update_params["parentFolderPath"] = parent_folder_path
646
+ if title:
647
+ update_params["title"] = title
648
+
649
+ content_info = unique_sdk.Content.update(
650
+ user_id=user_id, company_id=company_id, **update_params
651
+ )
652
+ return ContentInfo.model_validate(content_info, by_alias=True, by_name=True)
653
+
654
+
655
+ def delete_content(
656
+ user_id: str,
657
+ company_id: str,
658
+ *,
659
+ content_id: str | None = None,
660
+ file_path: str | None = None,
661
+ ) -> DeleteContentResponse:
662
+ if content_id:
663
+ resp = unique_sdk.Content.delete(
664
+ user_id=user_id, company_id=company_id, contentId=content_id
665
+ )
666
+ elif file_path:
667
+ resp = unique_sdk.Content.delete(
668
+ user_id=user_id, company_id=company_id, filePath=file_path
669
+ )
670
+ else:
671
+ raise ValueError("content_id or file_path must be provided")
672
+
673
+ return DeleteContentResponse.model_validate(resp, by_alias=True, by_name=True)
674
+
675
+
676
+ async def delete_content_async(
677
+ user_id: str,
678
+ company_id: str,
679
+ *,
680
+ content_id: str | None = None,
681
+ file_path: str | None = None,
682
+ ) -> DeleteContentResponse:
683
+ if content_id:
684
+ resp = await unique_sdk.Content.delete_async(
685
+ user_id=user_id, company_id=company_id, contentId=content_id
686
+ )
687
+ elif file_path:
688
+ resp = await unique_sdk.Content.delete_async(
689
+ user_id=user_id, company_id=company_id, filePath=file_path
690
+ )
691
+ else:
692
+ raise ValueError("content_id or file_path must be provided")
693
+
694
+ return DeleteContentResponse.model_validate(resp, by_alias=True, by_name=True)
@@ -1,7 +1,8 @@
1
1
  from datetime import datetime
2
2
  from enum import StrEnum
3
- from typing import Optional
3
+ from typing import Any, Optional
4
4
 
5
+ import unique_sdk
5
6
  from humps import camelize
6
7
  from pydantic import BaseModel, ConfigDict, Field
7
8
 
@@ -26,15 +27,41 @@ class ContentMetadata(BaseModel):
26
27
 
27
28
  class ContentChunk(BaseModel):
28
29
  model_config = model_config
29
- id: str
30
- text: str
31
- order: int
32
- key: str | None = None
33
- chunk_id: str | None = None
34
- url: str | None = None
35
- title: str | None = None
36
- start_page: int | None = None
37
- end_page: int | None = None
30
+ id: str = Field(
31
+ default="",
32
+ description="The id of the content this chunk belongs to. The id starts with 'cont_' followed by an alphanumeric string of length 24.",
33
+ examples=["cont_abcdefgehijklmnopqrstuvwx"],
34
+ )
35
+ text: str = Field(default="", description="The text content of the chunk.")
36
+ order: int = Field(
37
+ default=0,
38
+ description="The order of the chunk in the original content. Concatenating the chunks in order will give the original content.",
39
+ )
40
+ key: str | None = Field(
41
+ default=None,
42
+ description="The key of the chunk. For document chunks this is the the filename",
43
+ )
44
+ chunk_id: str | None = Field(
45
+ default=None,
46
+ description="The id of the chunk. The id starts with 'chunk_' followed by an alphanumeric string of length 24.",
47
+ examples=["chunk_abcdefgehijklmnopqrstuv"],
48
+ )
49
+ url: str | None = Field(
50
+ default=None,
51
+ description="For chunk retrieved from the web this is the url of the chunk.",
52
+ )
53
+ title: str | None = Field(
54
+ default=None,
55
+ description="The title of the chunk. For document chunks this is the title of the document.",
56
+ )
57
+ start_page: int | None = Field(
58
+ default=None,
59
+ description="The start page of the chunk. For document chunks this is the start page of the document.",
60
+ )
61
+ end_page: int | None = Field(
62
+ default=None,
63
+ description="The end page of the chunk. For document chunks this is the end page of the document.",
64
+ )
38
65
 
39
66
  object: str | None = None
40
67
  metadata: ContentMetadata | None = None
@@ -45,26 +72,64 @@ class ContentChunk(BaseModel):
45
72
 
46
73
  class Content(BaseModel):
47
74
  model_config = model_config
48
- id: str
49
- key: str
50
- title: str | None = None
75
+ id: str = Field(
76
+ default="",
77
+ description="The id of the content. The id starts with 'cont_' followed by an alphanumeric string of length 24.",
78
+ examples=["cont_abcdefgehijklmnopqrstuvwx"],
79
+ )
80
+ key: str = Field(
81
+ default="",
82
+ description="The key of the content. For documents this is the the filename",
83
+ )
84
+ title: str | None = Field(
85
+ default=None,
86
+ description="The title of the content. For documents this is the title of the document.",
87
+ )
51
88
  url: str | None = None
52
89
  chunks: list[ContentChunk] = []
53
90
  write_url: str | None = None
54
91
  read_url: str | None = None
55
92
  created_at: datetime | None = None
56
93
  updated_at: datetime | None = None
94
+ metadata: dict[str, Any] | None = None
95
+ ingestion_config: dict | None = None
57
96
 
58
97
 
59
98
  class ContentReference(BaseModel):
60
99
  model_config = model_config
61
- id: str
62
- message_id: str
100
+ id: str = Field(
101
+ default="",
102
+ description="The id of the content reference. Can be empty on the ChatMessage Object",
103
+ )
104
+ message_id: str = Field(
105
+ default="",
106
+ description="The id of the message that this reference belongs to. Can be empty on the ChatMessage Object",
107
+ )
63
108
  name: str
64
109
  sequence_number: int
65
110
  source: str
66
111
  source_id: str
67
112
  url: str
113
+ original_index: list[int] = Field(
114
+ default=[],
115
+ description="List of indices in the ChatMessage original_content this reference refers to. This is usually the id in the functionCallResponse. List type due to implementation in node-chat",
116
+ )
117
+
118
+ @classmethod
119
+ def from_sdk_reference(
120
+ cls, reference: unique_sdk.Message.Reference | unique_sdk.Space.Reference
121
+ ) -> "ContentReference":
122
+ kwargs = {
123
+ "name": reference["name"],
124
+ "url": reference["url"],
125
+ "sequence_number": reference["sequenceNumber"],
126
+ "source": reference["source"],
127
+ "source_id": reference["sourceId"],
128
+ }
129
+ if "originalIndex" in reference:
130
+ kwargs["original_index"] = reference["originalIndex"]
131
+
132
+ return cls.model_validate(kwargs)
68
133
 
69
134
 
70
135
  class ContentSearchType(StrEnum):
@@ -101,3 +166,45 @@ class ContentRerankerConfig(BaseModel):
101
166
  model_config = model_config
102
167
  deployment_name: str = Field(serialization_alias="deploymentName")
103
168
  options: dict | None = None
169
+
170
+
171
+ class ContentInfo(BaseModel):
172
+ model_config = model_config
173
+ id: str
174
+ object: str
175
+ key: str
176
+ url: str | None = None
177
+ title: str | None = None
178
+ metadata: dict[str, Any] | None = None
179
+ byte_size: int
180
+ mime_type: str
181
+ owner_id: str
182
+ created_at: datetime
183
+ updated_at: datetime
184
+ expires_at: datetime | None = None
185
+ deleted_at: datetime | None = None
186
+ expired_at: datetime | None = None
187
+
188
+
189
+ class PaginatedContentInfos(BaseModel):
190
+ model_config = model_config
191
+ object: str
192
+ content_infos: list[ContentInfo]
193
+ total_count: int
194
+
195
+
196
+ class FolderInfo(BaseModel):
197
+ model_config = model_config
198
+ id: str
199
+ name: str
200
+ ingestion_config: dict[str, Any]
201
+ createdAt: str | None
202
+ updatedAt: str | None
203
+ parentId: str | None
204
+ externalId: str | None
205
+
206
+
207
+ class DeleteContentResponse(BaseModel):
208
+ model_config = model_config
209
+ content_id: str
210
+ object: str