unique_toolkit 0.7.9__py3-none-any.whl → 1.33.3__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.
- unique_toolkit/__init__.py +36 -3
- unique_toolkit/_common/api_calling/human_verification_manager.py +357 -0
- unique_toolkit/_common/base_model_type_attribute.py +303 -0
- unique_toolkit/_common/chunk_relevancy_sorter/config.py +49 -0
- unique_toolkit/_common/chunk_relevancy_sorter/exception.py +5 -0
- unique_toolkit/_common/chunk_relevancy_sorter/schemas.py +46 -0
- unique_toolkit/_common/chunk_relevancy_sorter/service.py +374 -0
- unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +275 -0
- unique_toolkit/_common/default_language_model.py +12 -0
- unique_toolkit/_common/docx_generator/__init__.py +7 -0
- unique_toolkit/_common/docx_generator/config.py +12 -0
- unique_toolkit/_common/docx_generator/schemas.py +80 -0
- unique_toolkit/_common/docx_generator/service.py +225 -0
- unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
- unique_toolkit/_common/endpoint_builder.py +368 -0
- unique_toolkit/_common/endpoint_requestor.py +480 -0
- unique_toolkit/_common/exception.py +24 -0
- unique_toolkit/_common/experimental/endpoint_builder.py +368 -0
- unique_toolkit/_common/experimental/endpoint_requestor.py +488 -0
- unique_toolkit/_common/feature_flags/schema.py +9 -0
- unique_toolkit/_common/pydantic/rjsf_tags.py +936 -0
- unique_toolkit/_common/pydantic_helpers.py +174 -0
- unique_toolkit/_common/referencing.py +53 -0
- unique_toolkit/_common/string_utilities.py +140 -0
- unique_toolkit/_common/tests/test_referencing.py +521 -0
- unique_toolkit/_common/tests/test_string_utilities.py +506 -0
- unique_toolkit/_common/token/image_token_counting.py +67 -0
- unique_toolkit/_common/token/token_counting.py +204 -0
- unique_toolkit/_common/utils/__init__.py +1 -0
- unique_toolkit/_common/utils/files.py +43 -0
- unique_toolkit/_common/utils/image/encode.py +25 -0
- unique_toolkit/_common/utils/jinja/helpers.py +10 -0
- unique_toolkit/_common/utils/jinja/render.py +18 -0
- unique_toolkit/_common/utils/jinja/schema.py +65 -0
- unique_toolkit/_common/utils/jinja/utils.py +80 -0
- unique_toolkit/_common/utils/structured_output/__init__.py +1 -0
- unique_toolkit/_common/utils/structured_output/schema.py +5 -0
- unique_toolkit/_common/utils/write_configuration.py +51 -0
- unique_toolkit/_common/validators.py +101 -4
- unique_toolkit/agentic/__init__.py +1 -0
- unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +28 -0
- unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +278 -0
- unique_toolkit/agentic/evaluation/config.py +36 -0
- unique_toolkit/{evaluators → agentic/evaluation}/context_relevancy/prompts.py +25 -0
- unique_toolkit/agentic/evaluation/context_relevancy/schema.py +80 -0
- unique_toolkit/agentic/evaluation/context_relevancy/service.py +273 -0
- unique_toolkit/agentic/evaluation/evaluation_manager.py +218 -0
- unique_toolkit/agentic/evaluation/hallucination/constants.py +61 -0
- unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +112 -0
- unique_toolkit/{evaluators → agentic/evaluation}/hallucination/prompts.py +1 -1
- unique_toolkit/{evaluators → agentic/evaluation}/hallucination/service.py +20 -16
- unique_toolkit/{evaluators → agentic/evaluation}/hallucination/utils.py +32 -21
- unique_toolkit/{evaluators → agentic/evaluation}/output_parser.py +20 -2
- unique_toolkit/{evaluators → agentic/evaluation}/schemas.py +27 -7
- unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +253 -0
- unique_toolkit/agentic/evaluation/tests/test_output_parser.py +87 -0
- unique_toolkit/agentic/history_manager/history_construction_with_contents.py +298 -0
- unique_toolkit/agentic/history_manager/history_manager.py +241 -0
- unique_toolkit/agentic/history_manager/loop_token_reducer.py +484 -0
- unique_toolkit/agentic/history_manager/utils.py +96 -0
- unique_toolkit/agentic/message_log_manager/__init__.py +5 -0
- unique_toolkit/agentic/message_log_manager/service.py +93 -0
- unique_toolkit/agentic/postprocessor/postprocessor_manager.py +212 -0
- unique_toolkit/agentic/reference_manager/reference_manager.py +103 -0
- unique_toolkit/agentic/responses_api/__init__.py +19 -0
- unique_toolkit/agentic/responses_api/postprocessors/code_display.py +71 -0
- unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +297 -0
- unique_toolkit/agentic/responses_api/stream_handler.py +15 -0
- unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +141 -0
- unique_toolkit/agentic/thinking_manager/thinking_manager.py +103 -0
- unique_toolkit/agentic/tools/__init__.py +1 -0
- unique_toolkit/agentic/tools/a2a/__init__.py +36 -0
- unique_toolkit/agentic/tools/a2a/config.py +17 -0
- unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +15 -0
- unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +66 -0
- unique_toolkit/agentic/tools/a2a/evaluation/config.py +55 -0
- unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +260 -0
- unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +9 -0
- unique_toolkit/agentic/tools/a2a/manager.py +55 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +21 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +240 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +84 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/config.py +78 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/display.py +264 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/references.py +101 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +421 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +2103 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +603 -0
- unique_toolkit/agentic/tools/a2a/prompts.py +46 -0
- unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +6 -0
- unique_toolkit/agentic/tools/a2a/response_watcher/service.py +91 -0
- unique_toolkit/agentic/tools/a2a/tool/__init__.py +4 -0
- unique_toolkit/agentic/tools/a2a/tool/_memory.py +26 -0
- unique_toolkit/agentic/tools/a2a/tool/_schema.py +9 -0
- unique_toolkit/agentic/tools/a2a/tool/config.py +158 -0
- unique_toolkit/agentic/tools/a2a/tool/service.py +393 -0
- unique_toolkit/agentic/tools/agent_chunks_hanlder.py +65 -0
- unique_toolkit/agentic/tools/config.py +128 -0
- unique_toolkit/agentic/tools/factory.py +44 -0
- unique_toolkit/agentic/tools/mcp/__init__.py +4 -0
- unique_toolkit/agentic/tools/mcp/manager.py +71 -0
- unique_toolkit/agentic/tools/mcp/models.py +28 -0
- unique_toolkit/agentic/tools/mcp/tool_wrapper.py +234 -0
- unique_toolkit/agentic/tools/openai_builtin/__init__.py +11 -0
- unique_toolkit/agentic/tools/openai_builtin/base.py +46 -0
- unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +8 -0
- unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +88 -0
- unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +250 -0
- unique_toolkit/agentic/tools/openai_builtin/manager.py +79 -0
- unique_toolkit/agentic/tools/schemas.py +145 -0
- unique_toolkit/agentic/tools/test/test_mcp_manager.py +536 -0
- unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +445 -0
- unique_toolkit/agentic/tools/tool.py +187 -0
- unique_toolkit/agentic/tools/tool_manager.py +492 -0
- unique_toolkit/agentic/tools/tool_progress_reporter.py +285 -0
- unique_toolkit/agentic/tools/utils/__init__.py +19 -0
- unique_toolkit/agentic/tools/utils/execution/__init__.py +1 -0
- unique_toolkit/agentic/tools/utils/execution/execution.py +286 -0
- unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
- unique_toolkit/agentic/tools/utils/source_handling/schema.py +21 -0
- unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +207 -0
- unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +216 -0
- unique_toolkit/app/__init__.py +9 -0
- unique_toolkit/app/dev_util.py +180 -0
- unique_toolkit/app/fast_api_factory.py +131 -0
- unique_toolkit/app/init_sdk.py +32 -1
- unique_toolkit/app/schemas.py +206 -31
- unique_toolkit/app/unique_settings.py +367 -0
- unique_toolkit/app/webhook.py +77 -0
- unique_toolkit/chat/__init__.py +8 -1
- unique_toolkit/chat/deprecated/service.py +232 -0
- unique_toolkit/chat/functions.py +648 -78
- unique_toolkit/chat/rendering.py +34 -0
- unique_toolkit/chat/responses_api.py +461 -0
- unique_toolkit/chat/schemas.py +134 -2
- unique_toolkit/chat/service.py +115 -767
- unique_toolkit/content/functions.py +353 -8
- unique_toolkit/content/schemas.py +128 -15
- unique_toolkit/content/service.py +321 -45
- unique_toolkit/content/smart_rules.py +301 -0
- unique_toolkit/content/utils.py +10 -3
- unique_toolkit/data_extraction/README.md +96 -0
- unique_toolkit/data_extraction/__init__.py +11 -0
- unique_toolkit/data_extraction/augmented/__init__.py +5 -0
- unique_toolkit/data_extraction/augmented/service.py +93 -0
- unique_toolkit/data_extraction/base.py +25 -0
- unique_toolkit/data_extraction/basic/__init__.py +11 -0
- unique_toolkit/data_extraction/basic/config.py +18 -0
- unique_toolkit/data_extraction/basic/prompt.py +13 -0
- unique_toolkit/data_extraction/basic/service.py +55 -0
- unique_toolkit/embedding/service.py +103 -12
- unique_toolkit/framework_utilities/__init__.py +1 -0
- unique_toolkit/framework_utilities/langchain/__init__.py +10 -0
- unique_toolkit/framework_utilities/langchain/client.py +71 -0
- unique_toolkit/framework_utilities/langchain/history.py +19 -0
- unique_toolkit/framework_utilities/openai/__init__.py +6 -0
- unique_toolkit/framework_utilities/openai/client.py +84 -0
- unique_toolkit/framework_utilities/openai/message_builder.py +229 -0
- unique_toolkit/framework_utilities/utils.py +23 -0
- unique_toolkit/language_model/__init__.py +3 -0
- unique_toolkit/language_model/_responses_api_utils.py +93 -0
- unique_toolkit/language_model/builder.py +27 -11
- unique_toolkit/language_model/default_language_model.py +3 -0
- unique_toolkit/language_model/functions.py +345 -43
- unique_toolkit/language_model/infos.py +1288 -46
- unique_toolkit/language_model/reference.py +242 -0
- unique_toolkit/language_model/schemas.py +481 -49
- unique_toolkit/language_model/service.py +229 -28
- unique_toolkit/protocols/support.py +145 -0
- unique_toolkit/services/__init__.py +7 -0
- unique_toolkit/services/chat_service.py +1631 -0
- unique_toolkit/services/knowledge_base.py +1094 -0
- unique_toolkit/short_term_memory/service.py +178 -41
- unique_toolkit/smart_rules/__init__.py +0 -0
- unique_toolkit/smart_rules/compile.py +56 -0
- unique_toolkit/test_utilities/events.py +197 -0
- unique_toolkit-1.33.3.dist-info/METADATA +1145 -0
- unique_toolkit-1.33.3.dist-info/RECORD +205 -0
- unique_toolkit/evaluators/__init__.py +0 -1
- unique_toolkit/evaluators/config.py +0 -35
- unique_toolkit/evaluators/constants.py +0 -1
- unique_toolkit/evaluators/context_relevancy/constants.py +0 -32
- unique_toolkit/evaluators/context_relevancy/service.py +0 -53
- unique_toolkit/evaluators/context_relevancy/utils.py +0 -142
- unique_toolkit/evaluators/hallucination/constants.py +0 -41
- unique_toolkit-0.7.9.dist-info/METADATA +0 -413
- unique_toolkit-0.7.9.dist-info/RECORD +0 -64
- /unique_toolkit/{evaluators → agentic/evaluation}/exception.py +0 -0
- {unique_toolkit-0.7.9.dist-info → unique_toolkit-1.33.3.dist-info}/LICENSE +0 -0
- {unique_toolkit-0.7.9.dist-info → unique_toolkit-1.33.3.dist-info}/WHEEL +0 -0
|
@@ -3,7 +3,9 @@ import os
|
|
|
3
3
|
import re
|
|
4
4
|
import tempfile
|
|
5
5
|
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
6
7
|
|
|
8
|
+
import httpx
|
|
7
9
|
import requests
|
|
8
10
|
import unique_sdk
|
|
9
11
|
|
|
@@ -12,8 +14,12 @@ from unique_toolkit.content.constants import DEFAULT_SEARCH_LANGUAGE
|
|
|
12
14
|
from unique_toolkit.content.schemas import (
|
|
13
15
|
Content,
|
|
14
16
|
ContentChunk,
|
|
17
|
+
ContentInfo,
|
|
15
18
|
ContentRerankerConfig,
|
|
16
19
|
ContentSearchType,
|
|
20
|
+
DeleteContentResponse,
|
|
21
|
+
FolderInfo,
|
|
22
|
+
PaginatedContentInfos,
|
|
17
23
|
)
|
|
18
24
|
from unique_toolkit.content.utils import map_contents, map_to_content_chunks
|
|
19
25
|
|
|
@@ -33,6 +39,7 @@ def search_content_chunks(
|
|
|
33
39
|
chat_only: bool | None = None,
|
|
34
40
|
metadata_filter: dict | None = None,
|
|
35
41
|
content_ids: list[str] | None = None,
|
|
42
|
+
score_threshold: float | None = None,
|
|
36
43
|
) -> list[ContentChunk]:
|
|
37
44
|
"""
|
|
38
45
|
Performs a synchronous search for content chunks in the knowledge base.
|
|
@@ -47,6 +54,7 @@ def search_content_chunks(
|
|
|
47
54
|
chat_only (bool | None): Whether to search only in the current chat. Defaults to None.
|
|
48
55
|
metadata_filter (dict | None): UniqueQL metadata filter. If unspecified/None, it tries to use the metadata filter from the event. Defaults to None.
|
|
49
56
|
content_ids (list[str] | None): The content IDs to search. Defaults to None.
|
|
57
|
+
score_threshold (float | None): The minimum score threshold for results. Defaults to 0.
|
|
50
58
|
Returns:
|
|
51
59
|
list[ContentChunk]: The search results.
|
|
52
60
|
"""
|
|
@@ -72,6 +80,7 @@ def search_content_chunks(
|
|
|
72
80
|
chatOnly=chat_only,
|
|
73
81
|
metaDataFilter=metadata_filter,
|
|
74
82
|
contentIds=content_ids,
|
|
83
|
+
scoreThreshold=score_threshold,
|
|
75
84
|
)
|
|
76
85
|
return map_to_content_chunks(searches)
|
|
77
86
|
except Exception as e:
|
|
@@ -92,6 +101,7 @@ async def search_content_chunks_async(
|
|
|
92
101
|
chat_only: bool | None = None,
|
|
93
102
|
metadata_filter: dict | None = None,
|
|
94
103
|
content_ids: list[str] | None = None,
|
|
104
|
+
score_threshold: float | None = None,
|
|
95
105
|
):
|
|
96
106
|
"""
|
|
97
107
|
Performs an asynchronous search for content chunks in the knowledge base.
|
|
@@ -120,6 +130,7 @@ async def search_content_chunks_async(
|
|
|
120
130
|
chatOnly=chat_only,
|
|
121
131
|
metaDataFilter=metadata_filter,
|
|
122
132
|
contentIds=content_ids,
|
|
133
|
+
scoreThreshold=score_threshold,
|
|
123
134
|
)
|
|
124
135
|
return map_to_content_chunks(searches)
|
|
125
136
|
except Exception as e:
|
|
@@ -132,7 +143,8 @@ def search_contents(
|
|
|
132
143
|
company_id: str,
|
|
133
144
|
chat_id: str,
|
|
134
145
|
where: dict,
|
|
135
|
-
|
|
146
|
+
include_failed_content: bool = False,
|
|
147
|
+
) -> list[Content]:
|
|
136
148
|
"""
|
|
137
149
|
Performs an asynchronous search for content files in the knowledge base by filter.
|
|
138
150
|
|
|
@@ -155,6 +167,7 @@ def search_contents(
|
|
|
155
167
|
chatId=chat_id,
|
|
156
168
|
# TODO add type parameter in SDK
|
|
157
169
|
where=where, # type: ignore
|
|
170
|
+
includeFailedContent=include_failed_content,
|
|
158
171
|
)
|
|
159
172
|
return map_contents(contents)
|
|
160
173
|
except Exception as e:
|
|
@@ -167,6 +180,7 @@ async def search_contents_async(
|
|
|
167
180
|
company_id: str,
|
|
168
181
|
chat_id: str,
|
|
169
182
|
where: dict,
|
|
183
|
+
include_failed_content: bool = False,
|
|
170
184
|
):
|
|
171
185
|
"""Asynchronously searches for content in the knowledge base."""
|
|
172
186
|
if where.get("contentId"):
|
|
@@ -178,6 +192,7 @@ async def search_contents_async(
|
|
|
178
192
|
company_id=company_id,
|
|
179
193
|
chatId=chat_id,
|
|
180
194
|
where=where, # type: ignore
|
|
195
|
+
includeFailedContent=include_failed_content,
|
|
181
196
|
)
|
|
182
197
|
return map_contents(contents)
|
|
183
198
|
except Exception as e:
|
|
@@ -204,6 +219,73 @@ def _upsert_content(
|
|
|
204
219
|
) # type: ignore
|
|
205
220
|
|
|
206
221
|
|
|
222
|
+
async def _upsert_content_async(
|
|
223
|
+
user_id: str,
|
|
224
|
+
company_id: str,
|
|
225
|
+
input_data: dict,
|
|
226
|
+
scope_id: str | None = None,
|
|
227
|
+
chat_id: str | None = None,
|
|
228
|
+
file_url: str | None = None,
|
|
229
|
+
):
|
|
230
|
+
return await unique_sdk.Content.upsert_async(
|
|
231
|
+
user_id=user_id,
|
|
232
|
+
company_id=company_id,
|
|
233
|
+
input=input_data, # type: ignore
|
|
234
|
+
scopeId=scope_id,
|
|
235
|
+
chatId=chat_id,
|
|
236
|
+
fileUrl=file_url,
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
async def upload_content_from_bytes_async(
|
|
241
|
+
user_id: str,
|
|
242
|
+
company_id: str,
|
|
243
|
+
content: bytes,
|
|
244
|
+
content_name: str,
|
|
245
|
+
mime_type: str,
|
|
246
|
+
scope_id: str | None = None,
|
|
247
|
+
chat_id: str | None = None,
|
|
248
|
+
skip_ingestion: bool = False,
|
|
249
|
+
ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
|
|
250
|
+
metadata: dict[str, Any] | None = None,
|
|
251
|
+
) -> Content:
|
|
252
|
+
"""
|
|
253
|
+
Asynchronously uploads content to the knowledge base.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
user_id (str): The user ID.
|
|
257
|
+
company_id (str): The company ID.
|
|
258
|
+
content (bytes): The content to upload.
|
|
259
|
+
content_name (str): The name of the content.
|
|
260
|
+
mime_type (str): The MIME type of the content.
|
|
261
|
+
scope_id (str | None): The scope ID. Defaults to None.
|
|
262
|
+
chat_id (str | None): The chat ID. Defaults to None.
|
|
263
|
+
skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
|
|
264
|
+
ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
|
|
265
|
+
metadata ( dict[str, Any] | None): The metadata for the content. Defaults to None.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
Content: The uploaded content.
|
|
269
|
+
"""
|
|
270
|
+
|
|
271
|
+
try:
|
|
272
|
+
return await _trigger_upload_content_async(
|
|
273
|
+
user_id=user_id,
|
|
274
|
+
company_id=company_id,
|
|
275
|
+
content=content,
|
|
276
|
+
content_name=content_name,
|
|
277
|
+
mime_type=mime_type,
|
|
278
|
+
scope_id=scope_id,
|
|
279
|
+
chat_id=chat_id,
|
|
280
|
+
skip_ingestion=skip_ingestion,
|
|
281
|
+
ingestion_config=ingestion_config,
|
|
282
|
+
metadata=metadata,
|
|
283
|
+
)
|
|
284
|
+
except Exception as e:
|
|
285
|
+
logger.error(f"Error while uploading content: {e}")
|
|
286
|
+
raise e
|
|
287
|
+
|
|
288
|
+
|
|
207
289
|
def upload_content_from_bytes(
|
|
208
290
|
user_id: str,
|
|
209
291
|
company_id: str,
|
|
@@ -213,7 +295,9 @@ def upload_content_from_bytes(
|
|
|
213
295
|
scope_id: str | None = None,
|
|
214
296
|
chat_id: str | None = None,
|
|
215
297
|
skip_ingestion: bool = False,
|
|
216
|
-
|
|
298
|
+
ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
|
|
299
|
+
metadata: dict[str, Any] | None = None,
|
|
300
|
+
) -> Content:
|
|
217
301
|
"""
|
|
218
302
|
Uploads content to the knowledge base.
|
|
219
303
|
|
|
@@ -226,6 +310,8 @@ def upload_content_from_bytes(
|
|
|
226
310
|
scope_id (str | None): The scope ID. Defaults to None.
|
|
227
311
|
chat_id (str | None): The chat ID. Defaults to None.
|
|
228
312
|
skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
|
|
313
|
+
ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
|
|
314
|
+
metadata ( dict[str, Any] | None): The metadata for the content. Defaults to None.
|
|
229
315
|
|
|
230
316
|
Returns:
|
|
231
317
|
Content: The uploaded content.
|
|
@@ -241,6 +327,8 @@ def upload_content_from_bytes(
|
|
|
241
327
|
scope_id=scope_id,
|
|
242
328
|
chat_id=chat_id,
|
|
243
329
|
skip_ingestion=skip_ingestion,
|
|
330
|
+
ingestion_config=ingestion_config,
|
|
331
|
+
metadata=metadata,
|
|
244
332
|
)
|
|
245
333
|
except Exception as e:
|
|
246
334
|
logger.error(f"Error while uploading content: {e}")
|
|
@@ -256,7 +344,10 @@ def upload_content(
|
|
|
256
344
|
scope_id: str | None = None,
|
|
257
345
|
chat_id: str | None = None,
|
|
258
346
|
skip_ingestion: bool = False,
|
|
259
|
-
|
|
347
|
+
skip_excel_ingestion: bool = False,
|
|
348
|
+
ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
|
|
349
|
+
metadata: dict[str, Any] | None = None,
|
|
350
|
+
) -> Content:
|
|
260
351
|
"""
|
|
261
352
|
Uploads content to the knowledge base.
|
|
262
353
|
|
|
@@ -269,6 +360,9 @@ def upload_content(
|
|
|
269
360
|
scope_id (str | None): The scope ID. Defaults to None.
|
|
270
361
|
chat_id (str | None): The chat ID. Defaults to None.
|
|
271
362
|
skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
|
|
363
|
+
skip_excel_ingestion (bool): Whether to skip excel ingestion. Defaults to False.
|
|
364
|
+
ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
|
|
365
|
+
metadata ( dict[str, Any] | None): The metadata for the content. Defaults to None.
|
|
272
366
|
|
|
273
367
|
Returns:
|
|
274
368
|
Content: The uploaded content.
|
|
@@ -284,6 +378,9 @@ def upload_content(
|
|
|
284
378
|
scope_id=scope_id,
|
|
285
379
|
chat_id=chat_id,
|
|
286
380
|
skip_ingestion=skip_ingestion,
|
|
381
|
+
skip_excel_ingestion=skip_excel_ingestion,
|
|
382
|
+
ingestion_config=ingestion_config,
|
|
383
|
+
metadata=metadata,
|
|
287
384
|
)
|
|
288
385
|
except Exception as e:
|
|
289
386
|
logger.error(f"Error while uploading content: {e}")
|
|
@@ -299,7 +396,10 @@ def _trigger_upload_content(
|
|
|
299
396
|
scope_id: str | None = None,
|
|
300
397
|
chat_id: str | None = None,
|
|
301
398
|
skip_ingestion: bool = False,
|
|
302
|
-
|
|
399
|
+
skip_excel_ingestion: bool = False,
|
|
400
|
+
ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
|
|
401
|
+
metadata: dict[str, Any] | None = None,
|
|
402
|
+
) -> Content:
|
|
303
403
|
"""
|
|
304
404
|
Uploads content to the knowledge base.
|
|
305
405
|
|
|
@@ -312,6 +412,9 @@ def _trigger_upload_content(
|
|
|
312
412
|
scope_id (str | None): The scope ID. Defaults to None.
|
|
313
413
|
chat_id (str | None): The chat ID. Defaults to None.
|
|
314
414
|
skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
|
|
415
|
+
skip_excel_ingestion (bool): Whether to skip excel ingestion. Defaults to False.
|
|
416
|
+
ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
|
|
417
|
+
metadata (dict[str, Any] | None): The metadata for the content. Defaults to None.
|
|
315
418
|
|
|
316
419
|
Returns:
|
|
317
420
|
Content: The uploaded content.
|
|
@@ -368,16 +471,23 @@ def _trigger_upload_content(
|
|
|
368
471
|
logger.error(error_msg)
|
|
369
472
|
raise ValueError(error_msg)
|
|
370
473
|
|
|
474
|
+
if ingestion_config is None:
|
|
475
|
+
ingestion_config = {}
|
|
476
|
+
|
|
477
|
+
if skip_excel_ingestion:
|
|
478
|
+
ingestion_config["uniqueIngestionMode"] = "SKIP_EXCEL_INGESTION"
|
|
479
|
+
elif skip_ingestion:
|
|
480
|
+
ingestion_config["uniqueIngestionMode"] = "SKIP_INGESTION"
|
|
481
|
+
|
|
371
482
|
input_dict = {
|
|
372
483
|
"key": content_name,
|
|
373
484
|
"title": content_name,
|
|
374
485
|
"mimeType": mime_type,
|
|
375
486
|
"byteSize": byte_size,
|
|
487
|
+
"ingestionConfig": ingestion_config,
|
|
488
|
+
"metadata": metadata,
|
|
376
489
|
}
|
|
377
490
|
|
|
378
|
-
if skip_ingestion:
|
|
379
|
-
input_dict["ingestionConfig"] = {"uniqueIngestionMode": "SKIP_INGESTION"}
|
|
380
|
-
|
|
381
491
|
if chat_id:
|
|
382
492
|
_upsert_content(
|
|
383
493
|
user_id=user_id,
|
|
@@ -395,7 +505,131 @@ def _trigger_upload_content(
|
|
|
395
505
|
scope_id=scope_id,
|
|
396
506
|
) # type: ignore
|
|
397
507
|
|
|
398
|
-
return Content(
|
|
508
|
+
return Content.model_validate(created_content, by_alias=True, by_name=True)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
async def _trigger_upload_content_async(
|
|
512
|
+
user_id: str,
|
|
513
|
+
company_id: str,
|
|
514
|
+
content: str | Path | bytes,
|
|
515
|
+
content_name: str,
|
|
516
|
+
mime_type: str,
|
|
517
|
+
scope_id: str | None = None,
|
|
518
|
+
chat_id: str | None = None,
|
|
519
|
+
skip_ingestion: bool = False,
|
|
520
|
+
skip_excel_ingestion: bool = False,
|
|
521
|
+
ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
|
|
522
|
+
metadata: dict[str, Any] | None = None,
|
|
523
|
+
):
|
|
524
|
+
"""
|
|
525
|
+
Asynchronously uploads content to the knowledge base.
|
|
526
|
+
|
|
527
|
+
Args:
|
|
528
|
+
user_id (str): The user ID.
|
|
529
|
+
company_id (str): The company ID.
|
|
530
|
+
content (str | Path | bytes): The content to upload. If string or Path, file will be read from disk.
|
|
531
|
+
content_name (str): The name of the content.
|
|
532
|
+
mime_type (str): The MIME type of the content.
|
|
533
|
+
scope_id (str | None): The scope ID. Defaults to None.
|
|
534
|
+
chat_id (str | None): The chat ID. Defaults to None.
|
|
535
|
+
skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
|
|
536
|
+
skip_excel_ingestion (bool): Whether to skip excel ingestion. Defaults to False.
|
|
537
|
+
ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
|
|
538
|
+
metadata (dict[str, Any] | None): The metadata for the content. Defaults to None.
|
|
539
|
+
|
|
540
|
+
Returns:
|
|
541
|
+
Content: The uploaded content.
|
|
542
|
+
"""
|
|
543
|
+
# TODO: Remove code duplication with _trigger_upload_content
|
|
544
|
+
|
|
545
|
+
if not chat_id and not scope_id:
|
|
546
|
+
raise ValueError("chat_id or scope_id must be provided")
|
|
547
|
+
|
|
548
|
+
byte_size = (
|
|
549
|
+
os.path.getsize(content) if isinstance(content, (Path, str)) else len(content)
|
|
550
|
+
)
|
|
551
|
+
created_content = await _upsert_content_async(
|
|
552
|
+
user_id=user_id,
|
|
553
|
+
company_id=company_id,
|
|
554
|
+
input_data={
|
|
555
|
+
"key": content_name,
|
|
556
|
+
"title": content_name,
|
|
557
|
+
"mimeType": mime_type,
|
|
558
|
+
},
|
|
559
|
+
scope_id=scope_id,
|
|
560
|
+
chat_id=chat_id,
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
write_url = created_content["writeUrl"]
|
|
564
|
+
|
|
565
|
+
if not write_url:
|
|
566
|
+
error_msg = "Write url for uploaded content is missing"
|
|
567
|
+
logger.error(error_msg)
|
|
568
|
+
raise ValueError(error_msg)
|
|
569
|
+
|
|
570
|
+
headers = {
|
|
571
|
+
"X-Ms-Blob-Content-Type": mime_type,
|
|
572
|
+
"X-Ms-Blob-Type": "BlockBlob",
|
|
573
|
+
}
|
|
574
|
+
# upload to azure blob storage SAS url uploadUrl the pdf file translatedFile make sure it is treated as a application/pdf
|
|
575
|
+
async with httpx.AsyncClient() as client:
|
|
576
|
+
if isinstance(content, bytes):
|
|
577
|
+
response = await client.put(
|
|
578
|
+
url=write_url,
|
|
579
|
+
content=content,
|
|
580
|
+
headers=headers,
|
|
581
|
+
)
|
|
582
|
+
else:
|
|
583
|
+
with open(content, "rb") as file:
|
|
584
|
+
response = await client.put(
|
|
585
|
+
url=write_url,
|
|
586
|
+
content=file,
|
|
587
|
+
headers=headers,
|
|
588
|
+
)
|
|
589
|
+
response.raise_for_status()
|
|
590
|
+
|
|
591
|
+
read_url = created_content["readUrl"]
|
|
592
|
+
|
|
593
|
+
if not read_url:
|
|
594
|
+
error_msg = "Read url for uploaded content is missing"
|
|
595
|
+
logger.error(error_msg)
|
|
596
|
+
raise ValueError(error_msg)
|
|
597
|
+
|
|
598
|
+
if ingestion_config is None:
|
|
599
|
+
ingestion_config = {}
|
|
600
|
+
|
|
601
|
+
if skip_excel_ingestion:
|
|
602
|
+
ingestion_config["uniqueIngestionMode"] = "SKIP_EXCEL_INGESTION"
|
|
603
|
+
elif skip_ingestion:
|
|
604
|
+
ingestion_config["uniqueIngestionMode"] = "SKIP_INGESTION"
|
|
605
|
+
|
|
606
|
+
input_dict = {
|
|
607
|
+
"key": content_name,
|
|
608
|
+
"title": content_name,
|
|
609
|
+
"mimeType": mime_type,
|
|
610
|
+
"byteSize": byte_size,
|
|
611
|
+
"ingestionConfig": ingestion_config,
|
|
612
|
+
"metadata": metadata,
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
if chat_id:
|
|
616
|
+
await _upsert_content_async(
|
|
617
|
+
user_id=user_id,
|
|
618
|
+
company_id=company_id,
|
|
619
|
+
input_data=input_dict,
|
|
620
|
+
file_url=read_url,
|
|
621
|
+
chat_id=chat_id,
|
|
622
|
+
)
|
|
623
|
+
else:
|
|
624
|
+
await _upsert_content_async(
|
|
625
|
+
user_id=user_id,
|
|
626
|
+
company_id=company_id,
|
|
627
|
+
input_data=input_dict,
|
|
628
|
+
file_url=read_url,
|
|
629
|
+
scope_id=scope_id,
|
|
630
|
+
)
|
|
631
|
+
|
|
632
|
+
return Content.model_validate(created_content, by_alias=True, by_name=True)
|
|
399
633
|
|
|
400
634
|
|
|
401
635
|
def request_content_by_id(
|
|
@@ -543,3 +777,114 @@ def download_content(
|
|
|
543
777
|
raise Exception(error_msg)
|
|
544
778
|
|
|
545
779
|
return content_path
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
def get_content_info(
|
|
783
|
+
user_id: str,
|
|
784
|
+
company_id: str,
|
|
785
|
+
*,
|
|
786
|
+
metadata_filter: dict[str, Any] | None = None,
|
|
787
|
+
skip: int | None = None,
|
|
788
|
+
take: int | None = None,
|
|
789
|
+
file_path: str | None = None,
|
|
790
|
+
):
|
|
791
|
+
"""Gets the info of a content."""
|
|
792
|
+
|
|
793
|
+
get_info_params = unique_sdk.Content.ContentInfoParams(
|
|
794
|
+
metadataFilter=metadata_filter or None, # Dict cannot be empty
|
|
795
|
+
)
|
|
796
|
+
if skip:
|
|
797
|
+
get_info_params["skip"] = skip
|
|
798
|
+
if take:
|
|
799
|
+
get_info_params["take"] = take
|
|
800
|
+
if file_path:
|
|
801
|
+
get_info_params["filePath"] = file_path
|
|
802
|
+
|
|
803
|
+
content_info = unique_sdk.Content.get_infos(
|
|
804
|
+
user_id=user_id, company_id=company_id, **get_info_params
|
|
805
|
+
)
|
|
806
|
+
return PaginatedContentInfos.model_validate(
|
|
807
|
+
content_info, by_alias=True, by_name=True
|
|
808
|
+
)
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
def get_folder_info(user_id: str, company_id: str, *, scope_id: str) -> FolderInfo:
|
|
812
|
+
info = unique_sdk.Folder.get_info(
|
|
813
|
+
user_id=user_id, company_id=company_id, scopeId=scope_id
|
|
814
|
+
)
|
|
815
|
+
|
|
816
|
+
return FolderInfo.model_validate(info, by_alias=True, by_name=True)
|
|
817
|
+
|
|
818
|
+
|
|
819
|
+
def update_content(
|
|
820
|
+
user_id: str,
|
|
821
|
+
company_id: str,
|
|
822
|
+
*,
|
|
823
|
+
content_id: str,
|
|
824
|
+
metadata: dict[str, Any],
|
|
825
|
+
file_path: str | None = None,
|
|
826
|
+
owner_id: str | None = None,
|
|
827
|
+
parent_folder_path: str | None = None,
|
|
828
|
+
title: str | None = None,
|
|
829
|
+
) -> ContentInfo:
|
|
830
|
+
"""Updates the metadata of a content."""
|
|
831
|
+
|
|
832
|
+
update_params = unique_sdk.Content.UpdateParams(
|
|
833
|
+
contentId=content_id, metadata=metadata
|
|
834
|
+
)
|
|
835
|
+
|
|
836
|
+
if file_path:
|
|
837
|
+
update_params["filePath"] = file_path
|
|
838
|
+
if owner_id:
|
|
839
|
+
update_params["ownerId"] = owner_id
|
|
840
|
+
if parent_folder_path:
|
|
841
|
+
update_params["parentFolderPath"] = parent_folder_path
|
|
842
|
+
if title:
|
|
843
|
+
update_params["title"] = title
|
|
844
|
+
|
|
845
|
+
content_info = unique_sdk.Content.update(
|
|
846
|
+
user_id=user_id, company_id=company_id, **update_params
|
|
847
|
+
)
|
|
848
|
+
return ContentInfo.model_validate(content_info, by_alias=True, by_name=True)
|
|
849
|
+
|
|
850
|
+
|
|
851
|
+
def delete_content(
|
|
852
|
+
user_id: str,
|
|
853
|
+
company_id: str,
|
|
854
|
+
*,
|
|
855
|
+
content_id: str | None = None,
|
|
856
|
+
file_path: str | None = None,
|
|
857
|
+
) -> DeleteContentResponse:
|
|
858
|
+
if content_id:
|
|
859
|
+
resp = unique_sdk.Content.delete(
|
|
860
|
+
user_id=user_id, company_id=company_id, contentId=content_id
|
|
861
|
+
)
|
|
862
|
+
elif file_path:
|
|
863
|
+
resp = unique_sdk.Content.delete(
|
|
864
|
+
user_id=user_id, company_id=company_id, filePath=file_path
|
|
865
|
+
)
|
|
866
|
+
else:
|
|
867
|
+
raise ValueError("content_id or file_path must be provided")
|
|
868
|
+
|
|
869
|
+
return DeleteContentResponse.model_validate(resp, by_alias=True, by_name=True)
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
async def delete_content_async(
|
|
873
|
+
user_id: str,
|
|
874
|
+
company_id: str,
|
|
875
|
+
*,
|
|
876
|
+
content_id: str | None = None,
|
|
877
|
+
file_path: str | None = None,
|
|
878
|
+
) -> DeleteContentResponse:
|
|
879
|
+
if content_id:
|
|
880
|
+
resp = await unique_sdk.Content.delete_async(
|
|
881
|
+
user_id=user_id, company_id=company_id, contentId=content_id
|
|
882
|
+
)
|
|
883
|
+
elif file_path:
|
|
884
|
+
resp = await unique_sdk.Content.delete_async(
|
|
885
|
+
user_id=user_id, company_id=company_id, filePath=file_path
|
|
886
|
+
)
|
|
887
|
+
else:
|
|
888
|
+
raise ValueError("content_id or file_path must be provided")
|
|
889
|
+
|
|
890
|
+
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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,66 @@ class ContentChunk(BaseModel):
|
|
|
45
72
|
|
|
46
73
|
class Content(BaseModel):
|
|
47
74
|
model_config = model_config
|
|
48
|
-
id: str
|
|
49
|
-
|
|
50
|
-
|
|
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
|
+
expired_at: datetime | None = None
|
|
95
|
+
metadata: dict[str, Any] | None = None
|
|
96
|
+
ingestion_config: dict | None = None
|
|
97
|
+
ingestion_state: str | None = None
|
|
57
98
|
|
|
58
99
|
|
|
59
100
|
class ContentReference(BaseModel):
|
|
60
101
|
model_config = model_config
|
|
61
|
-
id: str
|
|
62
|
-
|
|
102
|
+
id: str = Field(
|
|
103
|
+
default="",
|
|
104
|
+
description="The id of the content reference. Can be empty on the ChatMessage Object",
|
|
105
|
+
)
|
|
106
|
+
message_id: str = Field(
|
|
107
|
+
default="",
|
|
108
|
+
description="The id of the message that this reference belongs to. Can be empty on the ChatMessage Object",
|
|
109
|
+
)
|
|
63
110
|
name: str
|
|
64
111
|
sequence_number: int
|
|
65
112
|
source: str
|
|
66
113
|
source_id: str
|
|
67
114
|
url: str
|
|
115
|
+
original_index: list[int] = Field(
|
|
116
|
+
default=[],
|
|
117
|
+
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",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
@classmethod
|
|
121
|
+
def from_sdk_reference(
|
|
122
|
+
cls, reference: unique_sdk.Message.Reference | unique_sdk.Space.Reference
|
|
123
|
+
) -> "ContentReference":
|
|
124
|
+
kwargs = {
|
|
125
|
+
"name": reference["name"],
|
|
126
|
+
"url": reference["url"],
|
|
127
|
+
"sequence_number": reference["sequenceNumber"],
|
|
128
|
+
"source": reference["source"],
|
|
129
|
+
"source_id": reference["sourceId"],
|
|
130
|
+
}
|
|
131
|
+
if "originalIndex" in reference:
|
|
132
|
+
kwargs["original_index"] = reference["originalIndex"]
|
|
133
|
+
|
|
134
|
+
return cls.model_validate(kwargs)
|
|
68
135
|
|
|
69
136
|
|
|
70
137
|
class ContentSearchType(StrEnum):
|
|
@@ -101,3 +168,49 @@ class ContentRerankerConfig(BaseModel):
|
|
|
101
168
|
model_config = model_config
|
|
102
169
|
deployment_name: str = Field(serialization_alias="deploymentName")
|
|
103
170
|
options: dict | None = None
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class ContentInfo(BaseModel):
|
|
174
|
+
model_config = model_config
|
|
175
|
+
id: str
|
|
176
|
+
object: str
|
|
177
|
+
key: str
|
|
178
|
+
url: str | None = None
|
|
179
|
+
title: str | None = None
|
|
180
|
+
metadata: dict[str, Any] | None = None
|
|
181
|
+
byte_size: int
|
|
182
|
+
mime_type: str
|
|
183
|
+
owner_id: str
|
|
184
|
+
created_at: datetime
|
|
185
|
+
updated_at: datetime
|
|
186
|
+
expires_at: datetime | None = None
|
|
187
|
+
deleted_at: datetime | None = None
|
|
188
|
+
expired_at: datetime | None = None
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class PaginatedContentInfos(BaseModel):
|
|
192
|
+
model_config = model_config
|
|
193
|
+
object: str
|
|
194
|
+
content_infos: list[ContentInfo]
|
|
195
|
+
total_count: int
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class BaseFolderInfo(BaseModel):
|
|
199
|
+
model_config = model_config
|
|
200
|
+
id: str
|
|
201
|
+
name: str
|
|
202
|
+
parent_id: str | None
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class FolderInfo(BaseFolderInfo):
|
|
206
|
+
model_config = model_config
|
|
207
|
+
ingestion_config: dict[str, Any]
|
|
208
|
+
created_at: str | None
|
|
209
|
+
updated_at: str | None
|
|
210
|
+
external_id: str | None
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
class DeleteContentResponse(BaseModel):
|
|
214
|
+
model_config = model_config
|
|
215
|
+
content_id: str
|
|
216
|
+
object: str
|