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.
Files changed (190) hide show
  1. unique_toolkit/__init__.py +36 -3
  2. unique_toolkit/_common/api_calling/human_verification_manager.py +357 -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 +225 -0
  14. unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
  15. unique_toolkit/_common/endpoint_builder.py +368 -0
  16. unique_toolkit/_common/endpoint_requestor.py +480 -0
  17. unique_toolkit/_common/exception.py +24 -0
  18. unique_toolkit/_common/experimental/endpoint_builder.py +368 -0
  19. unique_toolkit/_common/experimental/endpoint_requestor.py +488 -0
  20. unique_toolkit/_common/feature_flags/schema.py +9 -0
  21. unique_toolkit/_common/pydantic/rjsf_tags.py +936 -0
  22. unique_toolkit/_common/pydantic_helpers.py +174 -0
  23. unique_toolkit/_common/referencing.py +53 -0
  24. unique_toolkit/_common/string_utilities.py +140 -0
  25. unique_toolkit/_common/tests/test_referencing.py +521 -0
  26. unique_toolkit/_common/tests/test_string_utilities.py +506 -0
  27. unique_toolkit/_common/token/image_token_counting.py +67 -0
  28. unique_toolkit/_common/token/token_counting.py +204 -0
  29. unique_toolkit/_common/utils/__init__.py +1 -0
  30. unique_toolkit/_common/utils/files.py +43 -0
  31. unique_toolkit/_common/utils/image/encode.py +25 -0
  32. unique_toolkit/_common/utils/jinja/helpers.py +10 -0
  33. unique_toolkit/_common/utils/jinja/render.py +18 -0
  34. unique_toolkit/_common/utils/jinja/schema.py +65 -0
  35. unique_toolkit/_common/utils/jinja/utils.py +80 -0
  36. unique_toolkit/_common/utils/structured_output/__init__.py +1 -0
  37. unique_toolkit/_common/utils/structured_output/schema.py +5 -0
  38. unique_toolkit/_common/utils/write_configuration.py +51 -0
  39. unique_toolkit/_common/validators.py +101 -4
  40. unique_toolkit/agentic/__init__.py +1 -0
  41. unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +28 -0
  42. unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +278 -0
  43. unique_toolkit/agentic/evaluation/config.py +36 -0
  44. unique_toolkit/{evaluators → agentic/evaluation}/context_relevancy/prompts.py +25 -0
  45. unique_toolkit/agentic/evaluation/context_relevancy/schema.py +80 -0
  46. unique_toolkit/agentic/evaluation/context_relevancy/service.py +273 -0
  47. unique_toolkit/agentic/evaluation/evaluation_manager.py +218 -0
  48. unique_toolkit/agentic/evaluation/hallucination/constants.py +61 -0
  49. unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +112 -0
  50. unique_toolkit/{evaluators → agentic/evaluation}/hallucination/prompts.py +1 -1
  51. unique_toolkit/{evaluators → agentic/evaluation}/hallucination/service.py +20 -16
  52. unique_toolkit/{evaluators → agentic/evaluation}/hallucination/utils.py +32 -21
  53. unique_toolkit/{evaluators → agentic/evaluation}/output_parser.py +20 -2
  54. unique_toolkit/{evaluators → agentic/evaluation}/schemas.py +27 -7
  55. unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py +253 -0
  56. unique_toolkit/agentic/evaluation/tests/test_output_parser.py +87 -0
  57. unique_toolkit/agentic/history_manager/history_construction_with_contents.py +298 -0
  58. unique_toolkit/agentic/history_manager/history_manager.py +241 -0
  59. unique_toolkit/agentic/history_manager/loop_token_reducer.py +484 -0
  60. unique_toolkit/agentic/history_manager/utils.py +96 -0
  61. unique_toolkit/agentic/message_log_manager/__init__.py +5 -0
  62. unique_toolkit/agentic/message_log_manager/service.py +93 -0
  63. unique_toolkit/agentic/postprocessor/postprocessor_manager.py +212 -0
  64. unique_toolkit/agentic/reference_manager/reference_manager.py +103 -0
  65. unique_toolkit/agentic/responses_api/__init__.py +19 -0
  66. unique_toolkit/agentic/responses_api/postprocessors/code_display.py +71 -0
  67. unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +297 -0
  68. unique_toolkit/agentic/responses_api/stream_handler.py +15 -0
  69. unique_toolkit/agentic/short_term_memory_manager/persistent_short_term_memory_manager.py +141 -0
  70. unique_toolkit/agentic/thinking_manager/thinking_manager.py +103 -0
  71. unique_toolkit/agentic/tools/__init__.py +1 -0
  72. unique_toolkit/agentic/tools/a2a/__init__.py +36 -0
  73. unique_toolkit/agentic/tools/a2a/config.py +17 -0
  74. unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +15 -0
  75. unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +66 -0
  76. unique_toolkit/agentic/tools/a2a/evaluation/config.py +55 -0
  77. unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +260 -0
  78. unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2 +9 -0
  79. unique_toolkit/agentic/tools/a2a/manager.py +55 -0
  80. unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +21 -0
  81. unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +240 -0
  82. unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +84 -0
  83. unique_toolkit/agentic/tools/a2a/postprocessing/config.py +78 -0
  84. unique_toolkit/agentic/tools/a2a/postprocessing/display.py +264 -0
  85. unique_toolkit/agentic/tools/a2a/postprocessing/references.py +101 -0
  86. unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +421 -0
  87. unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +2103 -0
  88. unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +603 -0
  89. unique_toolkit/agentic/tools/a2a/prompts.py +46 -0
  90. unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +6 -0
  91. unique_toolkit/agentic/tools/a2a/response_watcher/service.py +91 -0
  92. unique_toolkit/agentic/tools/a2a/tool/__init__.py +4 -0
  93. unique_toolkit/agentic/tools/a2a/tool/_memory.py +26 -0
  94. unique_toolkit/agentic/tools/a2a/tool/_schema.py +9 -0
  95. unique_toolkit/agentic/tools/a2a/tool/config.py +158 -0
  96. unique_toolkit/agentic/tools/a2a/tool/service.py +393 -0
  97. unique_toolkit/agentic/tools/agent_chunks_hanlder.py +65 -0
  98. unique_toolkit/agentic/tools/config.py +128 -0
  99. unique_toolkit/agentic/tools/factory.py +44 -0
  100. unique_toolkit/agentic/tools/mcp/__init__.py +4 -0
  101. unique_toolkit/agentic/tools/mcp/manager.py +71 -0
  102. unique_toolkit/agentic/tools/mcp/models.py +28 -0
  103. unique_toolkit/agentic/tools/mcp/tool_wrapper.py +234 -0
  104. unique_toolkit/agentic/tools/openai_builtin/__init__.py +11 -0
  105. unique_toolkit/agentic/tools/openai_builtin/base.py +46 -0
  106. unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +8 -0
  107. unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +88 -0
  108. unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +250 -0
  109. unique_toolkit/agentic/tools/openai_builtin/manager.py +79 -0
  110. unique_toolkit/agentic/tools/schemas.py +145 -0
  111. unique_toolkit/agentic/tools/test/test_mcp_manager.py +536 -0
  112. unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +445 -0
  113. unique_toolkit/agentic/tools/tool.py +187 -0
  114. unique_toolkit/agentic/tools/tool_manager.py +492 -0
  115. unique_toolkit/agentic/tools/tool_progress_reporter.py +285 -0
  116. unique_toolkit/agentic/tools/utils/__init__.py +19 -0
  117. unique_toolkit/agentic/tools/utils/execution/__init__.py +1 -0
  118. unique_toolkit/agentic/tools/utils/execution/execution.py +286 -0
  119. unique_toolkit/agentic/tools/utils/source_handling/__init__.py +0 -0
  120. unique_toolkit/agentic/tools/utils/source_handling/schema.py +21 -0
  121. unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py +207 -0
  122. unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py +216 -0
  123. unique_toolkit/app/__init__.py +9 -0
  124. unique_toolkit/app/dev_util.py +180 -0
  125. unique_toolkit/app/fast_api_factory.py +131 -0
  126. unique_toolkit/app/init_sdk.py +32 -1
  127. unique_toolkit/app/schemas.py +206 -31
  128. unique_toolkit/app/unique_settings.py +367 -0
  129. unique_toolkit/app/webhook.py +77 -0
  130. unique_toolkit/chat/__init__.py +8 -1
  131. unique_toolkit/chat/deprecated/service.py +232 -0
  132. unique_toolkit/chat/functions.py +648 -78
  133. unique_toolkit/chat/rendering.py +34 -0
  134. unique_toolkit/chat/responses_api.py +461 -0
  135. unique_toolkit/chat/schemas.py +134 -2
  136. unique_toolkit/chat/service.py +115 -767
  137. unique_toolkit/content/functions.py +353 -8
  138. unique_toolkit/content/schemas.py +128 -15
  139. unique_toolkit/content/service.py +321 -45
  140. unique_toolkit/content/smart_rules.py +301 -0
  141. unique_toolkit/content/utils.py +10 -3
  142. unique_toolkit/data_extraction/README.md +96 -0
  143. unique_toolkit/data_extraction/__init__.py +11 -0
  144. unique_toolkit/data_extraction/augmented/__init__.py +5 -0
  145. unique_toolkit/data_extraction/augmented/service.py +93 -0
  146. unique_toolkit/data_extraction/base.py +25 -0
  147. unique_toolkit/data_extraction/basic/__init__.py +11 -0
  148. unique_toolkit/data_extraction/basic/config.py +18 -0
  149. unique_toolkit/data_extraction/basic/prompt.py +13 -0
  150. unique_toolkit/data_extraction/basic/service.py +55 -0
  151. unique_toolkit/embedding/service.py +103 -12
  152. unique_toolkit/framework_utilities/__init__.py +1 -0
  153. unique_toolkit/framework_utilities/langchain/__init__.py +10 -0
  154. unique_toolkit/framework_utilities/langchain/client.py +71 -0
  155. unique_toolkit/framework_utilities/langchain/history.py +19 -0
  156. unique_toolkit/framework_utilities/openai/__init__.py +6 -0
  157. unique_toolkit/framework_utilities/openai/client.py +84 -0
  158. unique_toolkit/framework_utilities/openai/message_builder.py +229 -0
  159. unique_toolkit/framework_utilities/utils.py +23 -0
  160. unique_toolkit/language_model/__init__.py +3 -0
  161. unique_toolkit/language_model/_responses_api_utils.py +93 -0
  162. unique_toolkit/language_model/builder.py +27 -11
  163. unique_toolkit/language_model/default_language_model.py +3 -0
  164. unique_toolkit/language_model/functions.py +345 -43
  165. unique_toolkit/language_model/infos.py +1288 -46
  166. unique_toolkit/language_model/reference.py +242 -0
  167. unique_toolkit/language_model/schemas.py +481 -49
  168. unique_toolkit/language_model/service.py +229 -28
  169. unique_toolkit/protocols/support.py +145 -0
  170. unique_toolkit/services/__init__.py +7 -0
  171. unique_toolkit/services/chat_service.py +1631 -0
  172. unique_toolkit/services/knowledge_base.py +1094 -0
  173. unique_toolkit/short_term_memory/service.py +178 -41
  174. unique_toolkit/smart_rules/__init__.py +0 -0
  175. unique_toolkit/smart_rules/compile.py +56 -0
  176. unique_toolkit/test_utilities/events.py +197 -0
  177. unique_toolkit-1.33.3.dist-info/METADATA +1145 -0
  178. unique_toolkit-1.33.3.dist-info/RECORD +205 -0
  179. unique_toolkit/evaluators/__init__.py +0 -1
  180. unique_toolkit/evaluators/config.py +0 -35
  181. unique_toolkit/evaluators/constants.py +0 -1
  182. unique_toolkit/evaluators/context_relevancy/constants.py +0 -32
  183. unique_toolkit/evaluators/context_relevancy/service.py +0 -53
  184. unique_toolkit/evaluators/context_relevancy/utils.py +0 -142
  185. unique_toolkit/evaluators/hallucination/constants.py +0 -41
  186. unique_toolkit-0.7.9.dist-info/METADATA +0 -413
  187. unique_toolkit-0.7.9.dist-info/RECORD +0 -64
  188. /unique_toolkit/{evaluators → agentic/evaluation}/exception.py +0 -0
  189. {unique_toolkit-0.7.9.dist-info → unique_toolkit-1.33.3.dist-info}/LICENSE +0 -0
  190. {unique_toolkit-0.7.9.dist-info → unique_toolkit-1.33.3.dist-info}/WHEEL +0 -0
@@ -0,0 +1,1631 @@
1
+ import logging
2
+ from typing import Any, Sequence
3
+
4
+ import unique_sdk
5
+ from openai.types.chat import ChatCompletionToolChoiceOptionParam
6
+ from openai.types.chat.chat_completion_message_param import ChatCompletionMessageParam
7
+ from openai.types.responses import (
8
+ ResponseIncludable,
9
+ ResponseInputItemParam,
10
+ ResponseOutputItem,
11
+ ResponseTextConfigParam,
12
+ ToolParam,
13
+ response_create_params,
14
+ )
15
+ from openai.types.shared_params import Metadata, Reasoning
16
+ from typing_extensions import deprecated
17
+
18
+ from unique_toolkit._common.utils.files import is_file_content, is_image_content
19
+ from unique_toolkit.chat.constants import (
20
+ DEFAULT_MAX_MESSAGES,
21
+ DEFAULT_PERCENT_OF_MAX_TOKENS,
22
+ DOMAIN_NAME,
23
+ )
24
+ from unique_toolkit.chat.deprecated.service import ChatServiceDeprecated
25
+ from unique_toolkit.chat.functions import (
26
+ create_message,
27
+ create_message_assessment,
28
+ create_message_assessment_async,
29
+ create_message_async,
30
+ create_message_execution,
31
+ create_message_execution_async,
32
+ create_message_log,
33
+ create_message_log_async,
34
+ get_full_history,
35
+ get_full_history_async,
36
+ get_message_execution,
37
+ get_message_execution_async,
38
+ get_selection_from_history,
39
+ modify_message,
40
+ modify_message_assessment,
41
+ modify_message_assessment_async,
42
+ modify_message_async,
43
+ stream_complete_with_references,
44
+ stream_complete_with_references_async,
45
+ update_message_execution,
46
+ update_message_execution_async,
47
+ update_message_log,
48
+ update_message_log_async,
49
+ )
50
+ from unique_toolkit.chat.responses_api import (
51
+ stream_responses_with_references,
52
+ stream_responses_with_references_async,
53
+ )
54
+ from unique_toolkit.chat.schemas import (
55
+ ChatMessage,
56
+ ChatMessageAssessment,
57
+ ChatMessageAssessmentLabel,
58
+ ChatMessageAssessmentStatus,
59
+ ChatMessageAssessmentType,
60
+ ChatMessageRole,
61
+ MessageExecution,
62
+ MessageExecutionType,
63
+ MessageExecutionUpdateStatus,
64
+ MessageLog,
65
+ MessageLogDetails,
66
+ MessageLogStatus,
67
+ MessageLogUncitedReferences,
68
+ )
69
+ from unique_toolkit.content.functions import (
70
+ download_content_to_bytes,
71
+ search_contents,
72
+ upload_content_from_bytes,
73
+ )
74
+ from unique_toolkit.content.schemas import (
75
+ Content,
76
+ ContentChunk,
77
+ ContentReference,
78
+ )
79
+ from unique_toolkit.language_model.constants import (
80
+ DEFAULT_COMPLETE_TEMPERATURE,
81
+ DEFAULT_COMPLETE_TIMEOUT,
82
+ )
83
+ from unique_toolkit.language_model.infos import (
84
+ LanguageModelName,
85
+ )
86
+ from unique_toolkit.language_model.schemas import (
87
+ LanguageModelMessageOptions,
88
+ LanguageModelMessages,
89
+ LanguageModelResponse,
90
+ LanguageModelStreamResponse,
91
+ LanguageModelTool,
92
+ LanguageModelToolDescription,
93
+ ResponsesLanguageModelStreamResponse,
94
+ )
95
+
96
+ logger = logging.getLogger(f"toolkit.{DOMAIN_NAME}.{__name__}")
97
+
98
+
99
+ class ChatService(ChatServiceDeprecated):
100
+ """Provides all functionalities to manage the chat session."""
101
+
102
+ async def update_debug_info_async(self, debug_info: dict):
103
+ """Updates the debug information for the chat session.
104
+
105
+ Args:
106
+ debug_info (dict): The new debug information.
107
+
108
+ """
109
+ return await modify_message_async(
110
+ user_id=self._user_id,
111
+ company_id=self._company_id,
112
+ assistant_message_id=self._assistant_message_id,
113
+ chat_id=self._chat_id,
114
+ user_message_id=self._user_message_id,
115
+ user_message_text=self._user_message_text,
116
+ assistant=False,
117
+ debug_info=debug_info,
118
+ )
119
+
120
+ def replace_debug_info(self, debug_info: dict):
121
+ """Replace the debug information in the last user message
122
+
123
+ Args:
124
+ debug_info (dict): The new debug information.
125
+
126
+ """
127
+ return modify_message(
128
+ user_id=self._user_id,
129
+ company_id=self._company_id,
130
+ assistant_message_id=self._assistant_message_id,
131
+ chat_id=self._chat_id,
132
+ user_message_id=self._user_message_id,
133
+ user_message_text=self._user_message_text,
134
+ assistant=False,
135
+ debug_info=debug_info,
136
+ )
137
+
138
+ # Message Methods
139
+ ############################################################################
140
+
141
+ def modify_user_message(
142
+ self,
143
+ content: str,
144
+ references: list[ContentReference] | None = None,
145
+ debug_info: dict | None = None,
146
+ message_id: str | None = None,
147
+ set_completed_at: bool | None = False,
148
+ ) -> ChatMessage:
149
+ """Modifies a user message in the chat session synchronously.
150
+
151
+ Args:
152
+ content (str): The new content for the message.
153
+ references (list[ContentReference]): list of ContentReference objects.
154
+ debug_info (dict[str, Any]]]): Debug information.
155
+ message_id (str, optional): The message ID, if not specified the last user message is edited.
156
+ set_completed_at (Optional[bool]): Whether to set the completedAt field with the current date time. Defaults to False.
157
+
158
+ Returns:
159
+ ChatMessage: The modified message.
160
+
161
+ Raises:
162
+ Exception: If the modification fails.
163
+
164
+ """
165
+ return modify_message(
166
+ user_id=self._user_id,
167
+ company_id=self._company_id,
168
+ assistant_message_id=self._assistant_message_id,
169
+ chat_id=self._chat_id,
170
+ user_message_id=self._user_message_id,
171
+ user_message_text=self._user_message_text,
172
+ assistant=False,
173
+ content=content,
174
+ references=references,
175
+ debug_info=debug_info,
176
+ message_id=message_id,
177
+ set_completed_at=set_completed_at or False,
178
+ )
179
+
180
+ async def modify_user_message_async(
181
+ self,
182
+ content: str,
183
+ references: list[ContentReference] = [],
184
+ debug_info: dict = {},
185
+ message_id: str | None = None,
186
+ set_completed_at: bool | None = False,
187
+ ) -> ChatMessage:
188
+ """Modifies a message in the chat session asynchronously.
189
+
190
+ Args:
191
+ content (str): The new content for the message.
192
+ message_id (str, optional): The message ID. Defaults to None, then the ChatState user message id is used.
193
+ references (list[ContentReference]): list of ContentReference objects. Defaults to None.
194
+ debug_info (dict[str, Any]]]): Debug information. Defaults to {}.
195
+ set_completed_at (bool, optional): Whether to set the completedAt field with the current date time. Defaults to False.
196
+
197
+ Returns:
198
+ ChatMessage: The modified message.
199
+
200
+ Raises:
201
+ Exception: If the modification fails.
202
+
203
+ """
204
+ return await modify_message_async(
205
+ user_id=self._user_id,
206
+ company_id=self._company_id,
207
+ assistant_message_id=self._assistant_message_id,
208
+ chat_id=self._chat_id,
209
+ user_message_id=self._user_message_id,
210
+ user_message_text=self._user_message_text,
211
+ assistant=False,
212
+ content=content,
213
+ references=references,
214
+ debug_info=debug_info,
215
+ message_id=message_id,
216
+ set_completed_at=set_completed_at or False,
217
+ )
218
+
219
+ def modify_assistant_message(
220
+ self,
221
+ content: str | None = None,
222
+ original_content: str | None = None,
223
+ references: list[ContentReference] | None = None,
224
+ debug_info: dict | None = None,
225
+ message_id: str | None = None,
226
+ set_completed_at: bool | None = None,
227
+ ) -> ChatMessage:
228
+ """Modifies a message in the chat session synchronously if parameter is not specified the corresponding field will remain as is.
229
+
230
+ Args:
231
+ content (str, optional): The new content for the message.
232
+ original_content (str, optional): The original content for the message.
233
+ references (list[ContentReference]): list of ContentReference objects. Defaults to [].
234
+ debug_info (dict[str, Any]]]): Debug information. Defaults to {}.
235
+ message_id (Optional[str]): The message ID. Defaults to None.
236
+ set_completed_at (Optional[bool]): Whether to set the completedAt field with the current date time. Defaults to False.
237
+
238
+ Returns:
239
+ ChatMessage: The modified message.
240
+
241
+ Raises:
242
+ Exception: If the modification fails.
243
+
244
+ """
245
+
246
+ return modify_message(
247
+ user_id=self._user_id,
248
+ company_id=self._company_id,
249
+ assistant_message_id=self._assistant_message_id,
250
+ chat_id=self._chat_id,
251
+ user_message_id=self._user_message_id,
252
+ user_message_text=self._user_message_text,
253
+ assistant=True,
254
+ content=content,
255
+ original_content=original_content,
256
+ references=references,
257
+ debug_info=debug_info,
258
+ message_id=message_id,
259
+ set_completed_at=set_completed_at or False,
260
+ )
261
+
262
+ async def modify_assistant_message_async(
263
+ self,
264
+ content: str | None = None,
265
+ original_content: str | None = None,
266
+ references: list[ContentReference] | None = None,
267
+ debug_info: dict | None = None,
268
+ message_id: str | None = None,
269
+ set_completed_at: bool | None = False,
270
+ ) -> ChatMessage:
271
+ """Modifies a message in the chat session asynchronously.
272
+
273
+ Args:
274
+ content (str, optional): The new content for the message.
275
+ original_content (str, optional): The original content for the message.
276
+ message_id (str, optional): The message ID. Defaults to None, then the ChatState assistant message id is used.
277
+ references (list[ContentReference]): list of ContentReference objects. Defaults to None.
278
+ debug_info (dict[str, Any]], optional): Debug information. Defaults to None.
279
+ set_completed_at (bool, optional): Whether to set the completedAt field with the current date time. Defaults to False.
280
+
281
+ Returns:
282
+ ChatMessage: The modified message.
283
+
284
+ Raises:
285
+ Exception: If the modification fails.
286
+
287
+ """
288
+ return await modify_message_async(
289
+ user_id=self._user_id,
290
+ company_id=self._company_id,
291
+ assistant_message_id=self._assistant_message_id,
292
+ chat_id=self._chat_id,
293
+ user_message_id=self._user_message_id,
294
+ user_message_text=self._user_message_text,
295
+ assistant=True,
296
+ content=content,
297
+ original_content=original_content,
298
+ references=references,
299
+ debug_info=debug_info,
300
+ message_id=message_id,
301
+ set_completed_at=set_completed_at or False,
302
+ )
303
+
304
+ def create_assistant_message(
305
+ self,
306
+ content: str,
307
+ original_content: str | None = None,
308
+ references: list[ContentReference] | None = None,
309
+ debug_info: dict | None = None,
310
+ set_completed_at: bool | None = False,
311
+ ) -> ChatMessage:
312
+ """Creates a message in the chat session synchronously.
313
+
314
+ Args:
315
+ content (str): The content for the message.
316
+ original_content (str, optional): The original content for the message.
317
+ references (list[ContentReference]): list of ContentReference objects. Defaults to None.
318
+ debug_info (dict[str, Any]]): Debug information. Defaults to None.
319
+ set_completed_at (Optional[bool]): Whether to set the completedAt field with the current date time. Defaults to False.
320
+
321
+ Returns:
322
+ ChatMessage: The created message.
323
+
324
+ Raises:
325
+ Exception: If the creation fails.
326
+
327
+ """
328
+ chat_message = create_message(
329
+ user_id=self._user_id,
330
+ company_id=self._company_id,
331
+ chat_id=self._chat_id,
332
+ assistant_id=self._assistant_id,
333
+ role=ChatMessageRole.ASSISTANT,
334
+ content=content,
335
+ original_content=original_content,
336
+ references=references,
337
+ debug_info=debug_info,
338
+ set_completed_at=set_completed_at,
339
+ )
340
+ # Update the assistant message id
341
+ self._assistant_message_id = chat_message.id or "unknown"
342
+ return chat_message
343
+
344
+ async def create_assistant_message_async(
345
+ self,
346
+ content: str,
347
+ original_content: str | None = None,
348
+ references: list[ContentReference] | None = None,
349
+ debug_info: dict | None = None,
350
+ set_completed_at: bool | None = False,
351
+ ) -> ChatMessage:
352
+ """Creates a message in the chat session asynchronously.
353
+
354
+ Args:
355
+ content (str): The content for the message.
356
+ original_content (str, optional): The original content for the message.
357
+ references (list[ContentReference]): list of references. Defaults to None.
358
+ debug_info (dict[str, Any]]): Debug information. Defaults to None.
359
+ set_completed_at (Optional[bool]): Whether to set the completedAt field with the current date time. Defaults to False.
360
+
361
+ Returns:
362
+ ChatMessage: The created message.
363
+
364
+ Raises:
365
+ Exception: If the creation fails.
366
+
367
+ """
368
+ chat_message = await create_message_async(
369
+ user_id=self._user_id,
370
+ company_id=self._company_id,
371
+ chat_id=self._chat_id,
372
+ assistant_id=self._assistant_id,
373
+ role=ChatMessageRole.ASSISTANT,
374
+ content=content,
375
+ original_content=original_content,
376
+ references=references,
377
+ debug_info=debug_info,
378
+ set_completed_at=set_completed_at,
379
+ )
380
+ # Update the assistant message id
381
+ self._assistant_message_id = chat_message.id or "unknown"
382
+ return chat_message
383
+
384
+ def create_user_message(
385
+ self,
386
+ content: str,
387
+ original_content: str | None = None,
388
+ references: list[ContentReference] | None = None,
389
+ debug_info: dict | None = None,
390
+ set_completed_at: bool | None = False,
391
+ ) -> ChatMessage:
392
+ """Creates a user message in the chat session synchronously.
393
+
394
+ Args:
395
+ content (str): The content for the message.
396
+ original_content (str, optional): The original content for the message.
397
+ references (list[ContentReference]): list of ContentReference objects. Defaults to None.
398
+ debug_info (dict[str, Any]]): Debug information. Defaults to None.
399
+ set_completed_at (Optional[bool]): Whether to set the completedAt field with the current date time. Defaults to False.
400
+
401
+ Returns:
402
+ ChatMessage: The created message.
403
+
404
+ Raises:
405
+ Exception: If the creation fails.
406
+
407
+ """
408
+ chat_message = create_message(
409
+ user_id=self._user_id,
410
+ company_id=self._company_id,
411
+ chat_id=self._chat_id,
412
+ assistant_id=self._assistant_id,
413
+ role=ChatMessageRole.USER,
414
+ content=content,
415
+ original_content=original_content,
416
+ references=references,
417
+ debug_info=debug_info,
418
+ set_completed_at=set_completed_at,
419
+ )
420
+ # Update the user message id
421
+ self._user_message_id = chat_message.id or "unknown"
422
+ return chat_message
423
+
424
+ async def create_user_message_async(
425
+ self,
426
+ content: str,
427
+ original_content: str | None = None,
428
+ references: list[ContentReference] | None = None,
429
+ debug_info: dict | None = None,
430
+ set_completed_at: bool | None = False,
431
+ ) -> ChatMessage:
432
+ """Creates a user message in the chat session asynchronously.
433
+
434
+ Args:
435
+ content (str): The content for the message.
436
+ original_content (str, optional): The original content for the message.
437
+ references (list[ContentReference]): list of references. Defaults to None.
438
+ debug_info (dict[str, Any]]): Debug information. Defaults to None.
439
+ set_completed_at (Optional[bool]): Whether to set the completedAt field with the current date time. Defaults to False.
440
+
441
+ Returns:
442
+ ChatMessage: The created message.
443
+
444
+ Raises:
445
+ Exception: If the creation fails.
446
+
447
+ """
448
+ chat_message = await create_message_async(
449
+ user_id=self._user_id,
450
+ company_id=self._company_id,
451
+ chat_id=self._chat_id,
452
+ assistant_id=self._assistant_id,
453
+ role=ChatMessageRole.USER,
454
+ content=content,
455
+ original_content=original_content,
456
+ references=references,
457
+ debug_info=debug_info,
458
+ set_completed_at=set_completed_at,
459
+ )
460
+ # Update the user message id
461
+ self._user_message_id = chat_message.id or "unknown"
462
+ return chat_message
463
+
464
+ def free_user_input(self) -> None:
465
+ """Unblocks the next user input"""
466
+ self.modify_assistant_message(set_completed_at=True)
467
+
468
+ # History Methods
469
+ ############################################################################
470
+
471
+ def get_full_history(self) -> list[ChatMessage]:
472
+ """Loads the full chat history for the chat session synchronously.
473
+
474
+ Returns:
475
+ list[ChatMessage]: The full chat history.
476
+
477
+ Raises:
478
+ Exception: If the loading fails.
479
+
480
+ """
481
+ return get_full_history(
482
+ event_user_id=self._user_id,
483
+ event_company_id=self._company_id,
484
+ event_payload_chat_id=self._chat_id,
485
+ )
486
+
487
+ async def get_full_history_async(self) -> list[ChatMessage]:
488
+ """Loads the full chat history for the chat session asynchronously.
489
+
490
+ Returns:
491
+ list[ChatMessage]: The full chat history.
492
+
493
+ Raises:
494
+ Exception: If the loading fails.
495
+
496
+ """
497
+ return await get_full_history_async(
498
+ event_user_id=self._user_id,
499
+ event_company_id=self._company_id,
500
+ event_payload_chat_id=self._chat_id,
501
+ )
502
+
503
+ def get_full_and_selected_history(
504
+ self,
505
+ token_limit: int,
506
+ percent_of_max_tokens: float = DEFAULT_PERCENT_OF_MAX_TOKENS,
507
+ max_messages: int = DEFAULT_MAX_MESSAGES,
508
+ ) -> tuple[list[ChatMessage], list[ChatMessage]]:
509
+ """Loads the chat history for the chat session synchronously.
510
+
511
+ Args:
512
+ token_limit (int): The maximum number of tokens to load.
513
+ percent_of_max_tokens (float): The percentage of the maximum tokens to load. Defaults to 0.15.
514
+ max_messages (int): The maximum number of messages to load. Defaults to 4.
515
+
516
+ Returns:
517
+ tuple[list[ChatMessage], list[ChatMessage]]: The selected and full chat history.
518
+
519
+ Raises:
520
+ Exception: If the loading fails.
521
+
522
+ """
523
+ full_history = get_full_history(
524
+ event_user_id=self._user_id,
525
+ event_company_id=self._company_id,
526
+ event_payload_chat_id=self._chat_id,
527
+ )
528
+ selected_history = get_selection_from_history(
529
+ full_history=full_history,
530
+ max_tokens=int(round(token_limit * percent_of_max_tokens)),
531
+ max_messages=max_messages,
532
+ )
533
+
534
+ return full_history, selected_history
535
+
536
+ async def get_full_and_selected_history_async(
537
+ self,
538
+ token_limit: int,
539
+ percent_of_max_tokens: float = DEFAULT_PERCENT_OF_MAX_TOKENS,
540
+ max_messages: int = DEFAULT_MAX_MESSAGES,
541
+ ) -> tuple[list[ChatMessage], list[ChatMessage]]:
542
+ """Loads the chat history for the chat session asynchronously.
543
+
544
+ Args:
545
+ token_limit (int): The maximum number of tokens to load.
546
+ percent_of_max_tokens (float): The percentage of the maximum tokens to load. Defaults to 0.15.
547
+ max_messages (int): The maximum number of messages to load. Defaults to 4.
548
+
549
+ Returns:
550
+ tuple[list[ChatMessage], list[ChatMessage]]: The selected and full chat history.
551
+
552
+ Raises:
553
+ Exception: If the loading fails.
554
+
555
+ """
556
+ full_history = await get_full_history_async(
557
+ event_user_id=self._user_id,
558
+ event_company_id=self._company_id,
559
+ event_payload_chat_id=self._chat_id,
560
+ )
561
+ selected_history = get_selection_from_history(
562
+ full_history=full_history,
563
+ max_tokens=int(round(token_limit * percent_of_max_tokens)),
564
+ max_messages=max_messages,
565
+ )
566
+
567
+ return full_history, selected_history
568
+
569
+ # Message Assessment Methods
570
+ ############################################################################
571
+
572
+ def create_message_assessment(
573
+ self,
574
+ assistant_message_id: str,
575
+ status: ChatMessageAssessmentStatus,
576
+ type: ChatMessageAssessmentType,
577
+ title: str | None = None,
578
+ explanation: str | None = None,
579
+ label: ChatMessageAssessmentLabel | None = None,
580
+ is_visible: bool = True,
581
+ ) -> ChatMessageAssessment:
582
+ """Creates a message assessment for an assistant message synchronously.
583
+
584
+ Args:
585
+ assistant_message_id (str): The ID of the assistant message to assess
586
+ status (MessageAssessmentStatus): The status of the assessment (e.g. "DONE")
587
+ type (MessageAssessmentType): The type of assessment (e.g. "HALLUCINATION")
588
+ title (str | None): The title of the assessment
589
+ explanation (str | None): Explanation of the assessment
590
+ label (MessageAssessmentLabel | None): The assessment label (e.g. "RED")
591
+ is_visible (bool): Whether the assessment is visible to users. Defaults to True.
592
+
593
+ Returns:
594
+ ChatMessageAssessment: The created message assessment
595
+
596
+ Raises:
597
+ Exception: If the creation fails
598
+
599
+ """
600
+ return create_message_assessment(
601
+ user_id=self._user_id,
602
+ company_id=self._company_id,
603
+ assistant_message_id=assistant_message_id,
604
+ status=status,
605
+ type=type,
606
+ title=title,
607
+ explanation=explanation,
608
+ label=label,
609
+ is_visible=is_visible,
610
+ )
611
+
612
+ async def create_message_assessment_async(
613
+ self,
614
+ assistant_message_id: str,
615
+ status: ChatMessageAssessmentStatus,
616
+ type: ChatMessageAssessmentType,
617
+ title: str | None = None,
618
+ explanation: str | None = None,
619
+ label: ChatMessageAssessmentLabel | None = None,
620
+ is_visible: bool = True,
621
+ ) -> ChatMessageAssessment:
622
+ """Creates a message assessment for an assistant message asynchronously.
623
+
624
+ Args:
625
+ assistant_message_id (str): The ID of the assistant message to assess
626
+ status (ChatMessageAssessmentStatus): The status of the assessment (e.g. "DONE")
627
+ type (ChatMessageAssessmentType): The type of assessment (e.g. "HALLUCINATION")
628
+ title (str | None): The title of the assessment
629
+ explanation (str | None): Explanation of the assessment
630
+ label (ChatMessageAssessmentLabel | None): The assessment label (e.g. "RED")
631
+ is_visible (bool): Whether the assessment is visible to users. Defaults to True.
632
+
633
+ Returns:
634
+ ChatMessageAssessment: The created message assessment
635
+
636
+ Raises:
637
+ Exception: If the creation fails
638
+
639
+ """
640
+ return await create_message_assessment_async(
641
+ user_id=self._user_id,
642
+ company_id=self._company_id,
643
+ assistant_message_id=assistant_message_id,
644
+ status=status,
645
+ type=type,
646
+ title=title,
647
+ explanation=explanation,
648
+ label=label,
649
+ is_visible=is_visible,
650
+ )
651
+
652
+ def modify_message_assessment(
653
+ self,
654
+ assistant_message_id: str,
655
+ status: ChatMessageAssessmentStatus,
656
+ type: ChatMessageAssessmentType,
657
+ title: str | None = None,
658
+ explanation: str | None = None,
659
+ label: ChatMessageAssessmentLabel | None = None,
660
+ ) -> ChatMessageAssessment:
661
+ """Modifies a message assessment for an assistant message synchronously.
662
+
663
+ Args:
664
+ assistant_message_id (str): The ID of the assistant message to assess
665
+ status (MessageAssessmentStatus): The status of the assessment (e.g. "DONE")
666
+ title (str | None): The title of the assessment
667
+ explanation (str | None): Explanation of the assessment
668
+ label (ChatMessageAssessmentLabel | None): The assessment label (e.g. "RED")
669
+ type (ChatMessageAssessmentType): The type of assessment (e.g. "HALLUCINATION")
670
+
671
+ Returns:
672
+ dict: The modified message assessment
673
+
674
+ Raises:
675
+ Exception: If the modification fails
676
+
677
+ """
678
+ return modify_message_assessment(
679
+ user_id=self._user_id,
680
+ company_id=self._company_id,
681
+ assistant_message_id=assistant_message_id,
682
+ status=status,
683
+ type=type,
684
+ title=title,
685
+ explanation=explanation,
686
+ label=label,
687
+ )
688
+
689
+ async def modify_message_assessment_async(
690
+ self,
691
+ assistant_message_id: str,
692
+ type: ChatMessageAssessmentType,
693
+ title: str | None = None,
694
+ status: ChatMessageAssessmentStatus | None = None,
695
+ explanation: str | None = None,
696
+ label: ChatMessageAssessmentLabel | None = None,
697
+ ) -> ChatMessageAssessment:
698
+ """Modifies a message assessment for an assistant message asynchronously.
699
+
700
+ Args:
701
+ assistant_message_id (str): The ID of the assistant message to assess
702
+ status (ChatMessageAssessmentStatus): The status of the assessment (e.g. "DONE")
703
+ title (str | None): The title of the assessment
704
+ explanation (str | None): Explanation of the assessment
705
+ label (ChatMessageAssessmentLabel | None): The assessment label (e.g. "RED")
706
+ type (ChatMessageAssessmentType): The type of assessment (e.g. "HALLUCINATION")
707
+
708
+ Returns:
709
+ ChatMessageAssessment: The modified message assessment
710
+
711
+ Raises:
712
+ Exception: If the modification fails
713
+
714
+ """
715
+ return await modify_message_assessment_async(
716
+ user_id=self._user_id,
717
+ company_id=self._company_id,
718
+ assistant_message_id=assistant_message_id,
719
+ status=status,
720
+ type=type,
721
+ title=title,
722
+ explanation=explanation,
723
+ label=label,
724
+ )
725
+
726
+ # Message Log Methods
727
+ ############################################################################
728
+
729
+ def create_message_log(
730
+ self,
731
+ *,
732
+ message_id: str,
733
+ text: str,
734
+ status: MessageLogStatus,
735
+ order: int,
736
+ details: MessageLogDetails | None = None,
737
+ uncited_references: MessageLogUncitedReferences | None = None,
738
+ references: list[ContentReference] | None = None,
739
+ ) -> MessageLog:
740
+ """Creates a message log for tracking execution steps synchronously.
741
+
742
+ Args:
743
+ message_id (str): The ID of the message this log belongs to
744
+ text (str): The log text content
745
+ status (MessageLogStatus): The status of this log entry
746
+ order (int): The order/sequence number of this log entry
747
+ details (MessageLogDetails | None): Additional details about this log entry
748
+ uncited_references (MessageLogUncitedReferences | None): References that are not cited
749
+ references (list[ContentReference] | None): List of references for this log
750
+
751
+ Returns:
752
+ MessageLog: The created message log
753
+
754
+ Raises:
755
+ Exception: If the creation fails
756
+
757
+ """
758
+ return create_message_log(
759
+ user_id=self._user_id,
760
+ company_id=self._company_id,
761
+ message_id=message_id,
762
+ text=text,
763
+ status=status,
764
+ order=order,
765
+ details=details,
766
+ uncited_references=uncited_references,
767
+ references=references,
768
+ )
769
+
770
+ async def create_message_log_async(
771
+ self,
772
+ *,
773
+ message_id: str,
774
+ text: str,
775
+ status: MessageLogStatus,
776
+ order: int,
777
+ details: MessageLogDetails | None = None,
778
+ uncited_references: MessageLogUncitedReferences | None = None,
779
+ references: list[ContentReference] | None = None,
780
+ ) -> MessageLog:
781
+ """Creates a message log for tracking execution steps asynchronously.
782
+
783
+ Args:
784
+ message_id (str): The ID of the message this log belongs to
785
+ text (str): The log text content
786
+ status (MessageLogStatus): The status of this log entry
787
+ order (int): The order/sequence number of this log entry
788
+ details (MessageLogDetails | None): Additional details about this log entry
789
+ uncited_references (MessageLogUncitedReferences | None): References that are not cited
790
+ references (list[ContentReference] | None): List of references for this log
791
+
792
+ Returns:
793
+ MessageLog: The created message log
794
+
795
+ Raises:
796
+ Exception: If the creation fails
797
+
798
+ """
799
+ return await create_message_log_async(
800
+ user_id=self._user_id,
801
+ company_id=self._company_id,
802
+ message_id=message_id,
803
+ text=text,
804
+ status=status,
805
+ order=order,
806
+ details=details,
807
+ uncited_references=uncited_references,
808
+ references=references,
809
+ )
810
+
811
+ def update_message_log(
812
+ self,
813
+ *,
814
+ message_log_id: str,
815
+ order: int,
816
+ text: str | None = None,
817
+ status: MessageLogStatus | None = None,
818
+ details: MessageLogDetails | None = None,
819
+ uncited_references: MessageLogUncitedReferences | None = None,
820
+ references: list[ContentReference] | None = None,
821
+ ) -> MessageLog:
822
+ """Updates a message log synchronously.
823
+
824
+ Args:
825
+ message_log_id (str): The ID of the message log to update
826
+ order (int): The order/sequence number (required)
827
+ text (str | None): The updated log text content
828
+ status (MessageLogStatus | None): The updated status
829
+ details (MessageLogDetails | None): Updated additional details
830
+ uncited_references (MessageLogUncitedReferences | None): Updated uncited references
831
+ references (list[ContentReference] | None): Updated list of references
832
+
833
+ Returns:
834
+ MessageLog: The updated message log
835
+
836
+ Raises:
837
+ Exception: If the update fails
838
+
839
+ """
840
+ return update_message_log(
841
+ user_id=self._user_id,
842
+ company_id=self._company_id,
843
+ message_log_id=message_log_id,
844
+ order=order,
845
+ text=text,
846
+ status=status,
847
+ details=details,
848
+ uncited_references=uncited_references,
849
+ references=references,
850
+ )
851
+
852
+ async def update_message_log_async(
853
+ self,
854
+ *,
855
+ message_log_id: str,
856
+ order: int,
857
+ text: str | None = None,
858
+ status: MessageLogStatus | None = None,
859
+ details: MessageLogDetails | None = None,
860
+ uncited_references: MessageLogUncitedReferences | None = None,
861
+ references: list[ContentReference] | None = None,
862
+ ) -> MessageLog:
863
+ """Updates a message log asynchronously.
864
+
865
+ Args:
866
+ message_log_id (str): The ID of the message log to update
867
+ order (int): The order/sequence number (required)
868
+ text (str | None): The updated log text content
869
+ status (MessageLogStatus | None): The updated status
870
+ details (MessageLogDetails | None): Updated additional details
871
+ uncited_references (MessageLogUncitedReferences | None): Updated uncited references
872
+ references (list[ContentReference] | None): Updated list of references
873
+
874
+ Returns:
875
+ MessageLog: The updated message log
876
+
877
+ Raises:
878
+ Exception: If the update fails
879
+
880
+ """
881
+ return await update_message_log_async(
882
+ user_id=self._user_id,
883
+ company_id=self._company_id,
884
+ message_log_id=message_log_id,
885
+ order=order,
886
+ text=text,
887
+ status=status,
888
+ details=details,
889
+ uncited_references=uncited_references,
890
+ references=references,
891
+ )
892
+
893
+ def create_assistant_message_log(
894
+ self,
895
+ *,
896
+ text: str,
897
+ status: MessageLogStatus,
898
+ order: int,
899
+ details: MessageLogDetails | None = None,
900
+ uncited_references: MessageLogUncitedReferences | None = None,
901
+ references: list[ContentReference] | None = None,
902
+ ) -> MessageLog:
903
+ """Creates a message log for the current assistant message synchronously.
904
+
905
+ This is a convenience method that uses the current assistant message ID.
906
+
907
+ Args:
908
+ text (str): The log text content
909
+ status (MessageLogStatus): The status of this log entry
910
+ order (int): The order/sequence number of this log entry
911
+ details (MessageLogDetails | None): Additional details about this log entry
912
+ uncited_references (MessageLogUncitedReferences | None): References that are not cited
913
+ references (list[ContentReference] | None): List of references for this log
914
+
915
+ Returns:
916
+ MessageLog: The created message log
917
+
918
+ Raises:
919
+ Exception: If the creation fails
920
+
921
+ """
922
+ return self.create_message_log(
923
+ message_id=self._assistant_message_id,
924
+ text=text,
925
+ status=status,
926
+ order=order,
927
+ details=details,
928
+ uncited_references=uncited_references,
929
+ references=references,
930
+ )
931
+
932
+ async def create_assistant_message_log_async(
933
+ self,
934
+ *,
935
+ text: str,
936
+ status: MessageLogStatus,
937
+ order: int,
938
+ details: MessageLogDetails | None = None,
939
+ uncited_references: MessageLogUncitedReferences | None = None,
940
+ references: list[ContentReference] | None = None,
941
+ ) -> MessageLog:
942
+ """Creates a message log for the current assistant message asynchronously.
943
+
944
+ This is a convenience method that uses the current assistant message ID.
945
+
946
+ Args:
947
+ text (str): The log text content
948
+ status (MessageLogStatus): The status of this log entry
949
+ order (int): The order/sequence number of this log entry
950
+ details (MessageLogDetails | None): Additional details about this log entry
951
+ uncited_references (MessageLogUncitedReferences | None): References that are not cited
952
+ references (list[ContentReference] | None): List of references for this log
953
+
954
+ Returns:
955
+ MessageLog: The created message log
956
+
957
+ Raises:
958
+ Exception: If the creation fails
959
+
960
+ """
961
+ return await self.create_message_log_async(
962
+ message_id=self._assistant_message_id,
963
+ text=text,
964
+ status=status,
965
+ order=order,
966
+ details=details,
967
+ uncited_references=uncited_references,
968
+ references=references,
969
+ )
970
+
971
+ # Message Execution Methods
972
+ ############################################################################
973
+
974
+ def create_message_execution(
975
+ self,
976
+ *,
977
+ message_id: str,
978
+ type: MessageExecutionType = MessageExecutionType.DEEP_RESEARCH,
979
+ seconds_remaining: int | None = None,
980
+ percentage_completed: int | None = None,
981
+ ) -> MessageExecution:
982
+ """Creates a message execution for tracking long-running operations synchronously.
983
+
984
+ Args:
985
+ message_id (str): The ID of the message this execution belongs to
986
+ type (MessageExecutionType): The type of execution. Defaults to DEEP_RESEARCH.
987
+ seconds_remaining (int | None): Estimated seconds remaining for completion
988
+ percentage_completed (int | None): Percentage of completion (0-100)
989
+
990
+ Returns:
991
+ MessageExecution: The created message execution
992
+
993
+ Raises:
994
+ Exception: If the creation fails
995
+
996
+ """
997
+ return create_message_execution(
998
+ user_id=self._user_id,
999
+ company_id=self._company_id,
1000
+ message_id=message_id,
1001
+ chat_id=self._chat_id,
1002
+ type=type,
1003
+ seconds_remaining=seconds_remaining,
1004
+ percentage_completed=percentage_completed,
1005
+ )
1006
+
1007
+ async def create_message_execution_async(
1008
+ self,
1009
+ *,
1010
+ message_id: str,
1011
+ type: MessageExecutionType = MessageExecutionType.DEEP_RESEARCH,
1012
+ seconds_remaining: int | None = None,
1013
+ percentage_completed: int | None = None,
1014
+ ) -> MessageExecution:
1015
+ """Creates a message execution for tracking long-running operations asynchronously.
1016
+
1017
+ Args:
1018
+ message_id (str): The ID of the message this execution belongs to
1019
+ type (MessageExecutionType): The type of execution. Defaults to DEEP_RESEARCH.
1020
+ seconds_remaining (int | None): Estimated seconds remaining for completion
1021
+ percentage_completed (int | None): Percentage of completion (0-100)
1022
+
1023
+ Returns:
1024
+ MessageExecution: The created message execution
1025
+
1026
+ Raises:
1027
+ Exception: If the creation fails
1028
+
1029
+ """
1030
+ return await create_message_execution_async(
1031
+ user_id=self._user_id,
1032
+ company_id=self._company_id,
1033
+ message_id=message_id,
1034
+ chat_id=self._chat_id,
1035
+ type=type,
1036
+ seconds_remaining=seconds_remaining,
1037
+ percentage_completed=percentage_completed,
1038
+ )
1039
+
1040
+ def get_message_execution(
1041
+ self,
1042
+ *,
1043
+ message_id: str,
1044
+ ) -> MessageExecution:
1045
+ """Gets a message execution by message ID synchronously.
1046
+
1047
+ Args:
1048
+ message_id (str): The ID of the message to get execution for
1049
+
1050
+ Returns:
1051
+ MessageExecution: The message execution
1052
+
1053
+ Raises:
1054
+ Exception: If the retrieval fails
1055
+
1056
+ """
1057
+ return get_message_execution(
1058
+ user_id=self._user_id,
1059
+ company_id=self._company_id,
1060
+ message_id=message_id,
1061
+ )
1062
+
1063
+ async def get_message_execution_async(
1064
+ self,
1065
+ *,
1066
+ message_id: str,
1067
+ ) -> MessageExecution:
1068
+ """Gets a message execution by message ID asynchronously.
1069
+
1070
+ Args:
1071
+ message_id (str): The ID of the message to get execution for
1072
+
1073
+ Returns:
1074
+ MessageExecution: The message execution
1075
+
1076
+ Raises:
1077
+ Exception: If the retrieval fails
1078
+
1079
+ """
1080
+ return await get_message_execution_async(
1081
+ user_id=self._user_id,
1082
+ company_id=self._company_id,
1083
+ message_id=message_id,
1084
+ )
1085
+
1086
+ def update_message_execution(
1087
+ self,
1088
+ *,
1089
+ message_id: str,
1090
+ status: MessageExecutionUpdateStatus | None = None,
1091
+ seconds_remaining: int | None = None,
1092
+ percentage_completed: int | None = None,
1093
+ ) -> MessageExecution:
1094
+ """Updates a message execution synchronously.
1095
+
1096
+ Args:
1097
+ message_id (str): The ID of the message to update execution for
1098
+ status (MessageExecutionUpdateStatus | None): The updated status (COMPLETED or FAILED). Defaults to None
1099
+ seconds_remaining (int | None): Updated estimated seconds remaining
1100
+ percentage_completed (int | None): Updated percentage of completion (0-100)
1101
+
1102
+ Returns:
1103
+ MessageExecution: The updated message execution
1104
+
1105
+ Raises:
1106
+ Exception: If the update fails
1107
+
1108
+ """
1109
+ return update_message_execution(
1110
+ user_id=self._user_id,
1111
+ company_id=self._company_id,
1112
+ message_id=message_id,
1113
+ status=status,
1114
+ seconds_remaining=seconds_remaining,
1115
+ percentage_completed=percentage_completed,
1116
+ )
1117
+
1118
+ async def update_message_execution_async(
1119
+ self,
1120
+ *,
1121
+ message_id: str,
1122
+ status: MessageExecutionUpdateStatus | None = None,
1123
+ seconds_remaining: int | None = None,
1124
+ percentage_completed: int | None = None,
1125
+ ) -> MessageExecution:
1126
+ """Updates a message execution asynchronously.
1127
+
1128
+ Args:
1129
+ message_id (str): The ID of the message to update execution for
1130
+ status (MessageExecutionUpdateStatus | None): The updated status (COMPLETED or FAILED). Defaults to None
1131
+ seconds_remaining (int | None): Updated estimated seconds remaining
1132
+ percentage_completed (int | None): Updated percentage of completion (0-100)
1133
+
1134
+ Returns:
1135
+ MessageExecution: The updated message execution
1136
+
1137
+ Raises:
1138
+ Exception: If the update fails
1139
+
1140
+ """
1141
+ return await update_message_execution_async(
1142
+ user_id=self._user_id,
1143
+ company_id=self._company_id,
1144
+ message_id=message_id,
1145
+ status=status,
1146
+ seconds_remaining=seconds_remaining,
1147
+ percentage_completed=percentage_completed,
1148
+ )
1149
+
1150
+ def create_assistant_message_execution(
1151
+ self,
1152
+ *,
1153
+ type: MessageExecutionType = MessageExecutionType.DEEP_RESEARCH,
1154
+ seconds_remaining: int | None = None,
1155
+ percentage_completed: int | None = None,
1156
+ ) -> MessageExecution:
1157
+ """Creates a message execution for the current assistant message synchronously.
1158
+
1159
+ This is a convenience method that uses the current assistant message ID.
1160
+
1161
+ Args:
1162
+ type (MessageExecutionType): The type of execution. Defaults to DEEP_RESEARCH.
1163
+ seconds_remaining (int | None): Estimated seconds remaining for completion
1164
+ percentage_completed (int | None): Percentage of completion (0-100)
1165
+
1166
+ Returns:
1167
+ MessageExecution: The created message execution
1168
+
1169
+ Raises:
1170
+ Exception: If the creation fails
1171
+
1172
+ """
1173
+ return self.create_message_execution(
1174
+ message_id=self._assistant_message_id,
1175
+ type=type,
1176
+ seconds_remaining=seconds_remaining,
1177
+ percentage_completed=percentage_completed,
1178
+ )
1179
+
1180
+ async def create_assistant_message_execution_async(
1181
+ self,
1182
+ *,
1183
+ type: MessageExecutionType = MessageExecutionType.DEEP_RESEARCH,
1184
+ seconds_remaining: int | None = None,
1185
+ percentage_completed: int | None = None,
1186
+ ) -> MessageExecution:
1187
+ """Creates a message execution for the current assistant message asynchronously.
1188
+
1189
+ This is a convenience method that uses the current assistant message ID.
1190
+
1191
+ Args:
1192
+ type (MessageExecutionType): The type of execution. Defaults to DEEP_RESEARCH.
1193
+ seconds_remaining (int | None): Estimated seconds remaining for completion
1194
+ percentage_completed (int | None): Percentage of completion (0-100)
1195
+
1196
+ Returns:
1197
+ MessageExecution: The created message execution
1198
+
1199
+ Raises:
1200
+ Exception: If the creation fails
1201
+
1202
+ """
1203
+ return await self.create_message_execution_async(
1204
+ message_id=self._assistant_message_id,
1205
+ type=type,
1206
+ seconds_remaining=seconds_remaining,
1207
+ percentage_completed=percentage_completed,
1208
+ )
1209
+
1210
+ def get_assistant_message_execution(self) -> MessageExecution:
1211
+ """Gets the message execution for the current assistant message synchronously.
1212
+
1213
+ This is a convenience method that uses the current assistant message ID.
1214
+
1215
+ Returns:
1216
+ MessageExecution: The message execution
1217
+
1218
+ Raises:
1219
+ Exception: If the retrieval fails
1220
+
1221
+ """
1222
+ return self.get_message_execution(message_id=self._assistant_message_id)
1223
+
1224
+ async def get_assistant_message_execution_async(self) -> MessageExecution:
1225
+ """Gets the message execution for the current assistant message asynchronously.
1226
+
1227
+ This is a convenience method that uses the current assistant message ID.
1228
+
1229
+ Returns:
1230
+ MessageExecution: The message execution
1231
+
1232
+ Raises:
1233
+ Exception: If the retrieval fails
1234
+
1235
+ """
1236
+ return await self.get_message_execution_async(
1237
+ message_id=self._assistant_message_id
1238
+ )
1239
+
1240
+ def update_assistant_message_execution(
1241
+ self,
1242
+ *,
1243
+ status: MessageExecutionUpdateStatus | None = None,
1244
+ seconds_remaining: int | None = None,
1245
+ percentage_completed: int | None = None,
1246
+ ) -> MessageExecution:
1247
+ """Updates the message execution for the current assistant message synchronously.
1248
+
1249
+ This is a convenience method that uses the current assistant message ID.
1250
+
1251
+ Args:
1252
+ status (MessageExecutionUpdateStatus | None): The updated status (COMPLETED or FAILED). Defaults to None
1253
+ seconds_remaining (int | None): Updated estimated seconds remaining
1254
+ percentage_completed (int | None): Updated percentage of completion (0-100)
1255
+
1256
+ Returns:
1257
+ MessageExecution: The updated message execution
1258
+
1259
+ Raises:
1260
+ Exception: If the update fails
1261
+
1262
+ """
1263
+ return self.update_message_execution(
1264
+ message_id=self._assistant_message_id,
1265
+ status=status,
1266
+ seconds_remaining=seconds_remaining,
1267
+ percentage_completed=percentage_completed,
1268
+ )
1269
+
1270
+ async def update_assistant_message_execution_async(
1271
+ self,
1272
+ *,
1273
+ status: MessageExecutionUpdateStatus | None = None,
1274
+ seconds_remaining: int | None = None,
1275
+ percentage_completed: int | None = None,
1276
+ ) -> MessageExecution:
1277
+ """Updates the message execution for the current assistant message asynchronously.
1278
+
1279
+ This is a convenience method that uses the current assistant message ID.
1280
+
1281
+ Args:
1282
+ status (MessageExecutionUpdateStatus | None): The updated status (COMPLETED or FAILED). Defaults to None
1283
+ seconds_remaining (int | None): Updated estimated seconds remaining
1284
+ percentage_completed (int | None): Updated percentage of completion (0-100)
1285
+
1286
+ Returns:
1287
+ MessageExecution: The updated message execution
1288
+
1289
+ Raises:
1290
+ Exception: If the update fails
1291
+
1292
+ """
1293
+ return await self.update_message_execution_async(
1294
+ message_id=self._assistant_message_id,
1295
+ status=status,
1296
+ seconds_remaining=seconds_remaining,
1297
+ percentage_completed=percentage_completed,
1298
+ )
1299
+
1300
+ # Language Model Methods
1301
+ ############################################################################
1302
+
1303
+ @deprecated("Use complete_with_references instead")
1304
+ def stream_complete(
1305
+ self,
1306
+ messages: LanguageModelMessages | list[ChatCompletionMessageParam],
1307
+ model_name: LanguageModelName | str,
1308
+ content_chunks: list[ContentChunk] | None = None,
1309
+ debug_info: dict = {},
1310
+ temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
1311
+ timeout: int = DEFAULT_COMPLETE_TIMEOUT,
1312
+ tools: Sequence[LanguageModelTool | LanguageModelToolDescription] | None = None,
1313
+ start_text: str | None = None,
1314
+ tool_choice: ChatCompletionToolChoiceOptionParam | None = None,
1315
+ other_options: dict | None = None,
1316
+ ) -> LanguageModelStreamResponse:
1317
+ return self.complete_with_references(
1318
+ messages=messages,
1319
+ model_name=model_name,
1320
+ content_chunks=content_chunks,
1321
+ debug_info=debug_info,
1322
+ temperature=temperature,
1323
+ timeout=timeout,
1324
+ tools=tools,
1325
+ start_text=start_text,
1326
+ tool_choice=tool_choice,
1327
+ other_options=other_options,
1328
+ )
1329
+
1330
+ def complete_with_references(
1331
+ self,
1332
+ messages: LanguageModelMessages | list[ChatCompletionMessageParam],
1333
+ model_name: LanguageModelName | str,
1334
+ content_chunks: list[ContentChunk] | None = None,
1335
+ debug_info: dict | None = None,
1336
+ temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
1337
+ timeout: int = DEFAULT_COMPLETE_TIMEOUT,
1338
+ tools: Sequence[LanguageModelTool | LanguageModelToolDescription] | None = None,
1339
+ start_text: str | None = None,
1340
+ tool_choice: ChatCompletionToolChoiceOptionParam | None = None,
1341
+ other_options: dict | None = None,
1342
+ ) -> LanguageModelStreamResponse:
1343
+ """Streams a completion in the chat session synchronously."""
1344
+ return stream_complete_with_references(
1345
+ company_id=self._company_id,
1346
+ user_id=self._user_id,
1347
+ assistant_message_id=self._assistant_message_id,
1348
+ user_message_id=self._user_message_id,
1349
+ chat_id=self._chat_id,
1350
+ assistant_id=self._assistant_id,
1351
+ messages=messages,
1352
+ model_name=model_name,
1353
+ content_chunks=content_chunks,
1354
+ debug_info=debug_info,
1355
+ temperature=temperature,
1356
+ timeout=timeout,
1357
+ tools=tools,
1358
+ start_text=start_text,
1359
+ tool_choice=tool_choice,
1360
+ other_options=other_options,
1361
+ )
1362
+
1363
+ def complete(
1364
+ self,
1365
+ messages: LanguageModelMessages | list[ChatCompletionMessageParam],
1366
+ model_name: LanguageModelName | str,
1367
+ content_chunks: list[ContentChunk] | None = None,
1368
+ debug_info: dict | None = None,
1369
+ temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
1370
+ timeout: int = DEFAULT_COMPLETE_TIMEOUT,
1371
+ tools: Sequence[LanguageModelTool | LanguageModelToolDescription] | None = None,
1372
+ start_text: str | None = None,
1373
+ tool_choice: ChatCompletionToolChoiceOptionParam | None = None,
1374
+ other_options: dict | None = None,
1375
+ ) -> LanguageModelResponse:
1376
+ response = self.complete_with_references(
1377
+ messages=messages,
1378
+ model_name=model_name,
1379
+ content_chunks=content_chunks,
1380
+ debug_info=debug_info,
1381
+ temperature=temperature,
1382
+ timeout=timeout,
1383
+ tools=tools,
1384
+ start_text=start_text,
1385
+ tool_choice=tool_choice,
1386
+ other_options=other_options,
1387
+ )
1388
+
1389
+ return LanguageModelResponse.from_stream_response(response)
1390
+
1391
+ @deprecated("use complete_with_references_async instead.")
1392
+ async def stream_complete_async(
1393
+ self,
1394
+ messages: LanguageModelMessages | list[ChatCompletionMessageParam],
1395
+ model_name: LanguageModelName | str,
1396
+ content_chunks: list[ContentChunk] | None = None,
1397
+ debug_info: dict | None = None,
1398
+ temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
1399
+ timeout: int = DEFAULT_COMPLETE_TIMEOUT,
1400
+ tools: Sequence[LanguageModelTool | LanguageModelToolDescription] | None = None,
1401
+ start_text: str | None = None,
1402
+ tool_choice: ChatCompletionToolChoiceOptionParam | None = None,
1403
+ other_options: dict | None = None,
1404
+ ) -> LanguageModelStreamResponse:
1405
+ """Stream a completion in the chat session asynchronously."""
1406
+ return await self.complete_with_references_async(
1407
+ messages=messages,
1408
+ model_name=model_name,
1409
+ content_chunks=content_chunks,
1410
+ debug_info=debug_info,
1411
+ temperature=temperature,
1412
+ timeout=timeout,
1413
+ tools=tools,
1414
+ start_text=start_text,
1415
+ tool_choice=tool_choice,
1416
+ other_options=other_options,
1417
+ )
1418
+
1419
+ async def complete_with_references_async(
1420
+ self,
1421
+ messages: LanguageModelMessages | list[ChatCompletionMessageParam],
1422
+ model_name: LanguageModelName | str,
1423
+ content_chunks: list[ContentChunk] | None = None,
1424
+ debug_info: dict | None = None,
1425
+ temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
1426
+ timeout: int = DEFAULT_COMPLETE_TIMEOUT,
1427
+ tools: Sequence[LanguageModelTool | LanguageModelToolDescription] | None = None,
1428
+ tool_choice: ChatCompletionToolChoiceOptionParam | None = None,
1429
+ start_text: str | None = None,
1430
+ other_options: dict | None = None,
1431
+ ) -> LanguageModelStreamResponse:
1432
+ return await stream_complete_with_references_async(
1433
+ company_id=self._company_id,
1434
+ user_id=self._user_id,
1435
+ assistant_message_id=self._assistant_message_id,
1436
+ user_message_id=self._user_message_id,
1437
+ chat_id=self._chat_id,
1438
+ assistant_id=self._assistant_id,
1439
+ messages=messages,
1440
+ model_name=model_name,
1441
+ content_chunks=content_chunks,
1442
+ debug_info=debug_info,
1443
+ temperature=temperature,
1444
+ timeout=timeout,
1445
+ tools=tools,
1446
+ start_text=start_text,
1447
+ tool_choice=tool_choice,
1448
+ other_options=other_options,
1449
+ )
1450
+
1451
+ async def complete_async(
1452
+ self,
1453
+ messages: LanguageModelMessages | list[ChatCompletionMessageParam],
1454
+ model_name: LanguageModelName | str,
1455
+ content_chunks: list[ContentChunk] | None,
1456
+ debug_info: dict | None = None,
1457
+ temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
1458
+ timeout: int = DEFAULT_COMPLETE_TIMEOUT,
1459
+ tools: Sequence[LanguageModelTool | LanguageModelToolDescription] | None = None,
1460
+ start_text: str | None = None,
1461
+ tool_choice: ChatCompletionToolChoiceOptionParam | None = None,
1462
+ other_options: dict | None = None,
1463
+ ) -> LanguageModelResponse:
1464
+ response = self.complete_with_references_async(
1465
+ messages=messages,
1466
+ model_name=model_name,
1467
+ content_chunks=content_chunks,
1468
+ debug_info=debug_info,
1469
+ temperature=temperature,
1470
+ timeout=timeout,
1471
+ tools=tools,
1472
+ start_text=start_text,
1473
+ tool_choice=tool_choice,
1474
+ other_options=other_options,
1475
+ )
1476
+
1477
+ return LanguageModelResponse.from_stream_response(await response)
1478
+
1479
+ def complete_responses_with_references(
1480
+ self,
1481
+ *,
1482
+ model_name: LanguageModelName | str,
1483
+ messages: str
1484
+ | LanguageModelMessages
1485
+ | Sequence[
1486
+ ResponseInputItemParam
1487
+ | LanguageModelMessageOptions
1488
+ | ResponseOutputItem # History is automatically convertible
1489
+ ],
1490
+ content_chunks: list[ContentChunk] | None = None,
1491
+ tools: Sequence[LanguageModelToolDescription | ToolParam] | None = None,
1492
+ temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
1493
+ debug_info: dict | None = None,
1494
+ start_text: str | None = None,
1495
+ include: list[ResponseIncludable] | None = None,
1496
+ instructions: str | None = None,
1497
+ max_output_tokens: int | None = None,
1498
+ metadata: Metadata | None = None,
1499
+ parallel_tool_calls: bool | None = None,
1500
+ text: ResponseTextConfigParam | None = None,
1501
+ tool_choice: response_create_params.ToolChoice | None = None,
1502
+ top_p: float | None = None,
1503
+ reasoning: Reasoning | None = None,
1504
+ other_options: dict | None = None,
1505
+ ) -> ResponsesLanguageModelStreamResponse:
1506
+ return stream_responses_with_references(
1507
+ company_id=self._company_id,
1508
+ user_id=self._user_id,
1509
+ assistant_message_id=self._assistant_message_id,
1510
+ user_message_id=self._user_message_id,
1511
+ chat_id=self._chat_id,
1512
+ assistant_id=self._assistant_id,
1513
+ model_name=model_name,
1514
+ messages=messages,
1515
+ content_chunks=content_chunks,
1516
+ tools=tools,
1517
+ temperature=temperature,
1518
+ debug_info=debug_info,
1519
+ start_text=start_text,
1520
+ include=include,
1521
+ instructions=instructions,
1522
+ max_output_tokens=max_output_tokens,
1523
+ metadata=metadata,
1524
+ parallel_tool_calls=parallel_tool_calls,
1525
+ text=text,
1526
+ tool_choice=tool_choice,
1527
+ top_p=top_p,
1528
+ reasoning=reasoning,
1529
+ other_options=other_options,
1530
+ )
1531
+
1532
+ async def complete_responses_with_references_async(
1533
+ self,
1534
+ *,
1535
+ model_name: LanguageModelName | str,
1536
+ messages: str
1537
+ | LanguageModelMessages
1538
+ | Sequence[
1539
+ ResponseInputItemParam | LanguageModelMessageOptions | ResponseOutputItem
1540
+ ],
1541
+ content_chunks: list[ContentChunk] | None = None,
1542
+ tools: Sequence[LanguageModelToolDescription | ToolParam] | None = None,
1543
+ temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
1544
+ debug_info: dict | None = None,
1545
+ start_text: str | None = None,
1546
+ include: list[ResponseIncludable] | None = None,
1547
+ instructions: str | None = None,
1548
+ max_output_tokens: int | None = None,
1549
+ metadata: Metadata | None = None,
1550
+ parallel_tool_calls: bool | None = None,
1551
+ text: ResponseTextConfigParam | None = None,
1552
+ tool_choice: response_create_params.ToolChoice | None = None,
1553
+ top_p: float | None = None,
1554
+ reasoning: Reasoning | None = None,
1555
+ other_options: dict | None = None,
1556
+ ) -> ResponsesLanguageModelStreamResponse:
1557
+ return await stream_responses_with_references_async(
1558
+ company_id=self._company_id,
1559
+ user_id=self._user_id,
1560
+ assistant_message_id=self._assistant_message_id,
1561
+ user_message_id=self._user_message_id,
1562
+ chat_id=self._chat_id,
1563
+ assistant_id=self._assistant_id,
1564
+ model_name=model_name,
1565
+ messages=messages,
1566
+ content_chunks=content_chunks,
1567
+ tools=tools,
1568
+ temperature=temperature,
1569
+ debug_info=debug_info,
1570
+ start_text=start_text,
1571
+ include=include,
1572
+ instructions=instructions,
1573
+ max_output_tokens=max_output_tokens,
1574
+ metadata=metadata,
1575
+ parallel_tool_calls=parallel_tool_calls,
1576
+ text=text,
1577
+ tool_choice=tool_choice,
1578
+ top_p=top_p,
1579
+ reasoning=reasoning,
1580
+ other_options=other_options,
1581
+ )
1582
+
1583
+ # Chat Content Methods
1584
+ ############################################################################
1585
+
1586
+ def upload_to_chat_from_bytes(
1587
+ self,
1588
+ *,
1589
+ content: bytes,
1590
+ content_name: str,
1591
+ mime_type: str,
1592
+ scope_id: str | None = None,
1593
+ skip_ingestion: bool = False,
1594
+ ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
1595
+ metadata: dict[str, Any] | None = None,
1596
+ ) -> Content:
1597
+ return upload_content_from_bytes(
1598
+ user_id=self._user_id,
1599
+ company_id=self._company_id,
1600
+ content=content,
1601
+ content_name=content_name,
1602
+ mime_type=mime_type,
1603
+ scope_id=scope_id,
1604
+ chat_id=self._chat_id,
1605
+ skip_ingestion=skip_ingestion,
1606
+ ingestion_config=ingestion_config,
1607
+ metadata=metadata,
1608
+ )
1609
+
1610
+ def download_chat_content_to_bytes(self, *, content_id: str) -> bytes:
1611
+ return download_content_to_bytes(
1612
+ user_id=self._user_id,
1613
+ company_id=self._company_id,
1614
+ content_id=content_id,
1615
+ chat_id=self._chat_id,
1616
+ )
1617
+
1618
+ def download_chat_images_and_documents(self) -> tuple[list[Content], list[Content]]:
1619
+ images: list[Content] = []
1620
+ files: list[Content] = []
1621
+ for c in search_contents(
1622
+ user_id=self._user_id,
1623
+ company_id=self._company_id,
1624
+ chat_id=self._chat_id,
1625
+ where={"ownerId": {"equals": self._chat_id}},
1626
+ ):
1627
+ if is_file_content(filename=c.key):
1628
+ files.append(c)
1629
+ if is_image_content(filename=c.key):
1630
+ images.append(c)
1631
+ return images, files