qanswer_sdk 3.1212.0__py3-none-any.whl → 3.1244.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qanswer_sdk/__init__.py +66 -43
- qanswer_sdk/api/__init__.py +7 -4
- qanswer_sdk/api/admin_api.py +590 -7695
- qanswer_sdk/api/ai_assistant_access_rights_api.py +72 -73
- qanswer_sdk/api/ai_assistant_api.py +567 -46
- qanswer_sdk/api/branding_api.py +4578 -0
- qanswer_sdk/api/chatbot_api.py +72 -87
- qanswer_sdk/api/{tag_api.py → connector_imap_connector_api.py} +415 -997
- qanswer_sdk/api/connector_rdf_api.py +30 -31
- qanswer_sdk/api/connectors_api.py +183 -166
- qanswer_sdk/api/connectors_data_api.py +345 -1
- qanswer_sdk/api/dataset_config_api.py +0 -245
- qanswer_sdk/api/llm_api.py +30 -30
- qanswer_sdk/api/payment_api.py +17 -16
- qanswer_sdk/api/speech_to_text_api.py +2 -2
- qanswer_sdk/api/task_chat_api.py +8 -7
- qanswer_sdk/api/task_rdf_linker_api.py +35 -36
- qanswer_sdk/api/task_rdf_sparql_endpoint_api.py +16 -16
- qanswer_sdk/api/task_report_copilot_api.py +895 -281
- qanswer_sdk/api/task_search_api.py +8 -7
- qanswer_sdk/api/tool_embedder_api.py +4040 -0
- qanswer_sdk/api/{user_api.py → tool_llm_api.py} +735 -2749
- qanswer_sdk/api/unit_organizations_api.py +4547 -0
- qanswer_sdk/api/unit_teams_api.py +3906 -0
- qanswer_sdk/api/{organizations_teams_api.py → unit_user_api.py} +1345 -1394
- qanswer_sdk/api_client.py +1 -1
- qanswer_sdk/configuration.py +1 -1
- qanswer_sdk/models/__init__.py +58 -38
- qanswer_sdk/models/aggregation.py +2 -2
- qanswer_sdk/models/ai_assistant_filter_dto.py +105 -0
- qanswer_sdk/models/{user_profile_paginated.py → ai_assistant_list.py} +18 -18
- qanswer_sdk/models/{embedding_model.py → available_aggregation.py} +13 -11
- qanswer_sdk/models/available_connectors_response.py +2 -2
- qanswer_sdk/models/{branding_data.py → branding_app_title.py} +4 -4
- qanswer_sdk/models/{api_response.py → branding_system_message.py} +8 -8
- qanswer_sdk/models/chat_task_settings.py +12 -12
- qanswer_sdk/models/chat_task_update.py +13 -5
- qanswer_sdk/models/chatbot_chat_payload.py +19 -2
- qanswer_sdk/models/chatbot_conversation_model.py +10 -0
- qanswer_sdk/models/chatbot_response.py +22 -2
- qanswer_sdk/models/{user_chatbot_setting_payload.py → chatbot_setting_dto.py} +12 -13
- qanswer_sdk/models/chatbot_setting_request.py +96 -0
- qanswer_sdk/models/{question_completion.py → clip_connector_file_structure.py} +9 -9
- qanswer_sdk/models/clip_connector_structure.py +97 -0
- qanswer_sdk/models/connector_model.py +2 -2
- qanswer_sdk/models/conversation_message.py +4 -12
- qanswer_sdk/models/{cost_summary.py → cost_summary_dto.py} +4 -4
- qanswer_sdk/models/create_connector_request.py +4 -2
- qanswer_sdk/models/create_imap_connector_request.py +105 -0
- qanswer_sdk/models/create_pinecone_connector_request.py +3 -1
- qanswer_sdk/models/create_sharepoint_connector_from_certificate_request.py +3 -1
- qanswer_sdk/models/create_sharepoint_connector_request.py +3 -1
- qanswer_sdk/models/dataset_detail_kg.py +27 -1
- qanswer_sdk/models/dataset_schema.py +4 -2
- qanswer_sdk/models/dataset_update_object.py +3 -1
- qanswer_sdk/models/delete_connector_model.py +2 -2
- qanswer_sdk/models/delete_connectors_response.py +2 -4
- qanswer_sdk/models/{json_nullable_source_metadata.py → duplicate_report_template_response.py} +11 -9
- qanswer_sdk/models/{json_nullable_file_failure_reason.py → email_folder.py} +12 -8
- qanswer_sdk/models/{embedding_endpoint.py → embedder_detailed_dto.py} +16 -8
- qanswer_sdk/models/{tag_payload.py → embedder_dto.py} +11 -7
- qanswer_sdk/models/{pageable_object.py → embedder_list_dto.py} +20 -20
- qanswer_sdk/models/embedding_endpoint_create.py +3 -1
- qanswer_sdk/models/embedding_endpoint_update.py +4 -2
- qanswer_sdk/models/{sort_object.py → entity_description.py} +16 -12
- qanswer_sdk/models/{dataset_description.py → entity_description_dto.py} +9 -7
- qanswer_sdk/models/file_model.py +2 -2
- qanswer_sdk/models/imap_add_payload.py +103 -0
- qanswer_sdk/models/imap_additional_fields.py +101 -0
- qanswer_sdk/models/imap_file_metadata.py +114 -0
- qanswer_sdk/models/imap_search_response.py +113 -0
- qanswer_sdk/models/llm.py +129 -0
- qanswer_sdk/models/llm_consumption.py +118 -0
- qanswer_sdk/models/{pageable.py → llm_context_ranges.py} +14 -13
- qanswer_sdk/models/{llm_cost.py → llm_cost_filter.py} +11 -7
- qanswer_sdk/models/llm_cost_list.py +101 -0
- qanswer_sdk/models/llm_detailed_dto.py +179 -0
- qanswer_sdk/models/{llm_details.py → llm_dto.py} +14 -18
- qanswer_sdk/models/llm_endpoint.py +8 -2
- qanswer_sdk/models/llm_endpoint_read_input.py +173 -0
- qanswer_sdk/models/llm_endpoint_read_output.py +173 -0
- qanswer_sdk/models/llm_filter_dto.py +99 -0
- qanswer_sdk/models/llm_list_detailed_dto.py +101 -0
- qanswer_sdk/models/llm_list_dto.py +101 -0
- qanswer_sdk/models/modify_connector_request.py +5 -11
- qanswer_sdk/models/{o_auth_service.py → o_auth_service_dto.py} +4 -4
- qanswer_sdk/models/organization_admin.py +95 -0
- qanswer_sdk/models/organization_filter_dto.py +97 -0
- qanswer_sdk/models/organization_list_dto.py +101 -0
- qanswer_sdk/models/organization_llm.py +103 -0
- qanswer_sdk/models/{plan.py → plan_dto.py} +4 -4
- qanswer_sdk/models/prompt_token_count_details.py +3 -3
- qanswer_sdk/models/rag_payload.py +4 -4
- qanswer_sdk/models/rag_response.py +4 -2
- qanswer_sdk/models/relation_extraction_task_settings.py +12 -10
- qanswer_sdk/models/relation_extraction_task_update.py +14 -4
- qanswer_sdk/models/report_copilot_slot_task_settings.py +12 -10
- qanswer_sdk/models/report_copilot_slot_task_update.py +13 -3
- qanswer_sdk/models/report_copilot_task_settings.py +12 -10
- qanswer_sdk/models/report_copilot_task_update.py +14 -4
- qanswer_sdk/models/{report_copilot_template.py → report_template.py} +17 -7
- qanswer_sdk/models/{report_copilot_create_payload.py → report_template_create_payload.py} +4 -4
- qanswer_sdk/models/{report_copilot_template_simplified.py → report_template_simplified.py} +11 -7
- qanswer_sdk/models/{report_copilot_export_template_as_docx_payload_simplified.py → report_template_simplified_payload.py} +4 -4
- qanswer_sdk/models/{report_copilot_update_payload.py → report_template_update_payload.py} +15 -9
- qanswer_sdk/models/search_task_settings.py +12 -12
- qanswer_sdk/models/search_task_update.py +13 -3
- qanswer_sdk/models/{set_logo1_request.py → set_logo2_request.py} +4 -4
- qanswer_sdk/models/shared_organization_access.py +7 -3
- qanswer_sdk/models/shared_team_access.py +10 -4
- qanswer_sdk/models/slot.py +5 -1
- qanswer_sdk/models/slot_update.py +5 -1
- qanswer_sdk/models/socket_conversation_message.py +3 -11
- qanswer_sdk/models/socket_file_metadata.py +17 -11
- qanswer_sdk/models/source_metadata.py +109 -0
- qanswer_sdk/models/{tag_qa_list_payload.py → subscription_response.py} +22 -21
- qanswer_sdk/models/{team_with_count.py → team_admin.py} +8 -8
- qanswer_sdk/models/{team_filter.py → team_filter_dto.py} +16 -6
- qanswer_sdk/models/team_list_dto.py +101 -0
- qanswer_sdk/models/{available_endpoints_response.py → template_clip_structure_input.py} +14 -14
- qanswer_sdk/models/{available_embedding_models_response.py → template_clip_structure_output.py} +14 -14
- qanswer_sdk/models/test_imap_connection_payload.py +95 -0
- qanswer_sdk/models/text2_sparql_payload.py +4 -4
- qanswer_sdk/models/text2_sparql_task_settings.py +12 -10
- qanswer_sdk/models/text2_sparql_task_update.py +14 -4
- qanswer_sdk/models/{user_chatbot_setting_response.py → user_chatbot_setting.py} +24 -24
- qanswer_sdk/models/user_dataset.py +38 -2
- qanswer_sdk/models/{qa_metadata_payload.py → user_dataset_shared.py} +27 -37
- qanswer_sdk/models/{user_filter.py → user_filter_dto.py} +4 -4
- qanswer_sdk/models/{user_profile.py → user_profile_dto.py} +10 -10
- qanswer_sdk/models/user_profile_list_dto.py +3 -3
- qanswer_sdk/models/widget_configs.py +4 -2
- {qanswer_sdk-3.1212.0.dist-info → qanswer_sdk-3.1244.0.dist-info}/METADATA +2 -2
- {qanswer_sdk-3.1212.0.dist-info → qanswer_sdk-3.1244.0.dist-info}/RECORD +135 -112
- qanswer_sdk/api/llm_consumption_controller_api.py +0 -310
- qanswer_sdk/models/organization_filter.py +0 -87
- qanswer_sdk/models/page_organization.py +0 -123
- qanswer_sdk/models/page_team_with_count.py +0 -123
- qanswer_sdk/models/tag_qa_payload.py +0 -91
- {qanswer_sdk-3.1212.0.dist-info → qanswer_sdk-3.1244.0.dist-info}/WHEEL +0 -0
@@ -17,9 +17,9 @@ import pprint
|
|
17
17
|
import re # noqa: F401
|
18
18
|
import json
|
19
19
|
|
20
|
-
from pydantic import BaseModel, ConfigDict, StrictBool, StrictFloat, StrictInt, StrictStr, field_validator
|
20
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr, field_validator
|
21
21
|
from typing import Any, ClassVar, Dict, List, Optional, Union
|
22
|
-
from qanswer_sdk.models.
|
22
|
+
from qanswer_sdk.models.llm_endpoint_read_output import LLMEndpointReadOutput
|
23
23
|
from typing import Optional, Set
|
24
24
|
from typing_extensions import Self
|
25
25
|
|
@@ -28,7 +28,6 @@ class ChatTaskSettings(BaseModel):
|
|
28
28
|
ChatTaskSettings
|
29
29
|
""" # noqa: E501
|
30
30
|
prompt: Optional[StrictStr] = None
|
31
|
-
llm_choice: Optional[StrictStr] = None
|
32
31
|
bot_seed: Optional[StrictInt] = None
|
33
32
|
bot_temperature: Optional[Union[StrictFloat, StrictInt]] = None
|
34
33
|
bot_answer_length: Optional[StrictStr] = None
|
@@ -36,16 +35,17 @@ class ChatTaskSettings(BaseModel):
|
|
36
35
|
stream_speed: Optional[Union[StrictFloat, StrictInt]] = None
|
37
36
|
context_window: Optional[StrictInt] = None
|
38
37
|
max_tokens: Optional[StrictInt] = None
|
38
|
+
slots_values: Optional[Dict[str, StrictStr]] = None
|
39
39
|
bot_name: Optional[StrictStr] = None
|
40
40
|
bot_description: Optional[StrictStr] = None
|
41
|
-
|
41
|
+
llm_id: Optional[StrictInt] = Field(default=None, description="The LLM ID. This field is populated based on the llm_choice.")
|
42
|
+
llm_endpoint: Optional[LLMEndpointReadOutput] = None
|
42
43
|
query_expansion_prompt: Optional[StrictStr] = None
|
43
44
|
show_date_in_sources: Optional[StrictBool] = None
|
44
|
-
slots_values: Optional[Dict[str, StrictStr]] = None
|
45
45
|
selected_aggregations: Optional[List[StrictStr]] = None
|
46
46
|
chat_initial_message: Optional[StrictStr] = None
|
47
47
|
human_takeover: Optional[StrictBool] = None
|
48
|
-
__properties: ClassVar[List[str]] = ["prompt", "
|
48
|
+
__properties: ClassVar[List[str]] = ["prompt", "bot_seed", "bot_temperature", "bot_answer_length", "number_of_references", "stream_speed", "context_window", "max_tokens", "slots_values", "bot_name", "bot_description", "llm_id", "llm_endpoint", "query_expansion_prompt", "show_date_in_sources", "selected_aggregations", "chat_initial_message", "human_takeover"]
|
49
49
|
|
50
50
|
@field_validator('bot_answer_length')
|
51
51
|
def bot_answer_length_validate_enum(cls, value):
|
@@ -96,9 +96,9 @@ class ChatTaskSettings(BaseModel):
|
|
96
96
|
exclude=excluded_fields,
|
97
97
|
exclude_none=True,
|
98
98
|
)
|
99
|
-
# override the default output from pydantic by calling `to_dict()` of
|
100
|
-
if self.
|
101
|
-
_dict['
|
99
|
+
# override the default output from pydantic by calling `to_dict()` of llm_endpoint
|
100
|
+
if self.llm_endpoint:
|
101
|
+
_dict['llm_endpoint'] = self.llm_endpoint.to_dict()
|
102
102
|
return _dict
|
103
103
|
|
104
104
|
@classmethod
|
@@ -112,7 +112,6 @@ class ChatTaskSettings(BaseModel):
|
|
112
112
|
|
113
113
|
_obj = cls.model_validate({
|
114
114
|
"prompt": obj.get("prompt"),
|
115
|
-
"llm_choice": obj.get("llm_choice"),
|
116
115
|
"bot_seed": obj.get("bot_seed"),
|
117
116
|
"bot_temperature": obj.get("bot_temperature"),
|
118
117
|
"bot_answer_length": obj.get("bot_answer_length"),
|
@@ -120,12 +119,13 @@ class ChatTaskSettings(BaseModel):
|
|
120
119
|
"stream_speed": obj.get("stream_speed"),
|
121
120
|
"context_window": obj.get("context_window"),
|
122
121
|
"max_tokens": obj.get("max_tokens"),
|
122
|
+
"slots_values": obj.get("slots_values"),
|
123
123
|
"bot_name": obj.get("bot_name"),
|
124
124
|
"bot_description": obj.get("bot_description"),
|
125
|
-
"
|
125
|
+
"llm_id": obj.get("llm_id"),
|
126
|
+
"llm_endpoint": LLMEndpointReadOutput.from_dict(obj["llm_endpoint"]) if obj.get("llm_endpoint") is not None else None,
|
126
127
|
"query_expansion_prompt": obj.get("query_expansion_prompt"),
|
127
128
|
"show_date_in_sources": obj.get("show_date_in_sources"),
|
128
|
-
"slots_values": obj.get("slots_values"),
|
129
129
|
"selected_aggregations": obj.get("selected_aggregations"),
|
130
130
|
"chat_initial_message": obj.get("chat_initial_message"),
|
131
131
|
"human_takeover": obj.get("human_takeover")
|
@@ -17,8 +17,9 @@ import pprint
|
|
17
17
|
import re # noqa: F401
|
18
18
|
import json
|
19
19
|
|
20
|
-
from pydantic import BaseModel, ConfigDict, StrictBool, StrictFloat, StrictInt, StrictStr, field_validator
|
20
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictFloat, StrictInt, StrictStr, field_validator
|
21
21
|
from typing import Any, ClassVar, Dict, List, Optional, Union
|
22
|
+
from qanswer_sdk.models.llm_endpoint_read_input import LLMEndpointReadInput
|
22
23
|
from typing import Optional, Set
|
23
24
|
from typing_extensions import Self
|
24
25
|
|
@@ -27,7 +28,7 @@ class ChatTaskUpdate(BaseModel):
|
|
27
28
|
ChatTaskUpdate
|
28
29
|
""" # noqa: E501
|
29
30
|
prompt: Optional[StrictStr] = None
|
30
|
-
llm_choice: Optional[StrictStr] = None
|
31
|
+
llm_choice: Optional[StrictStr] = Field(default=None, description="The LLM choice. If not provided, the system default will be used.")
|
31
32
|
bot_seed: Optional[StrictInt] = None
|
32
33
|
bot_temperature: Optional[Union[StrictFloat, StrictInt]] = None
|
33
34
|
bot_answer_length: Optional[StrictStr] = None
|
@@ -35,15 +36,17 @@ class ChatTaskUpdate(BaseModel):
|
|
35
36
|
stream_speed: Optional[Union[StrictFloat, StrictInt]] = None
|
36
37
|
context_window: Optional[StrictInt] = None
|
37
38
|
max_tokens: Optional[StrictInt] = None
|
39
|
+
slots_values: Optional[Dict[str, StrictStr]] = None
|
38
40
|
bot_name: Optional[StrictStr] = None
|
39
41
|
bot_description: Optional[StrictStr] = None
|
42
|
+
llm_id: Optional[StrictInt] = Field(default=None, description="The LLM ID. This field is populated based on the llm_choice.")
|
43
|
+
llm_endpoint: Optional[LLMEndpointReadInput] = None
|
40
44
|
query_expansion_prompt: Optional[StrictStr] = None
|
41
45
|
show_date_in_sources: Optional[StrictBool] = None
|
42
|
-
slots_values: Optional[Dict[str, StrictStr]] = None
|
43
46
|
selected_aggregations: Optional[List[StrictStr]] = None
|
44
47
|
chat_initial_message: Optional[StrictStr] = None
|
45
48
|
human_takeover: Optional[StrictBool] = None
|
46
|
-
__properties: ClassVar[List[str]] = ["prompt", "llm_choice", "bot_seed", "bot_temperature", "bot_answer_length", "number_of_references", "stream_speed", "context_window", "max_tokens", "bot_name", "bot_description", "
|
49
|
+
__properties: ClassVar[List[str]] = ["prompt", "llm_choice", "bot_seed", "bot_temperature", "bot_answer_length", "number_of_references", "stream_speed", "context_window", "max_tokens", "slots_values", "bot_name", "bot_description", "llm_id", "llm_endpoint", "query_expansion_prompt", "show_date_in_sources", "selected_aggregations", "chat_initial_message", "human_takeover"]
|
47
50
|
|
48
51
|
@field_validator('bot_answer_length')
|
49
52
|
def bot_answer_length_validate_enum(cls, value):
|
@@ -94,6 +97,9 @@ class ChatTaskUpdate(BaseModel):
|
|
94
97
|
exclude=excluded_fields,
|
95
98
|
exclude_none=True,
|
96
99
|
)
|
100
|
+
# override the default output from pydantic by calling `to_dict()` of llm_endpoint
|
101
|
+
if self.llm_endpoint:
|
102
|
+
_dict['llm_endpoint'] = self.llm_endpoint.to_dict()
|
97
103
|
return _dict
|
98
104
|
|
99
105
|
@classmethod
|
@@ -115,11 +121,13 @@ class ChatTaskUpdate(BaseModel):
|
|
115
121
|
"stream_speed": obj.get("stream_speed"),
|
116
122
|
"context_window": obj.get("context_window"),
|
117
123
|
"max_tokens": obj.get("max_tokens"),
|
124
|
+
"slots_values": obj.get("slots_values"),
|
118
125
|
"bot_name": obj.get("bot_name"),
|
119
126
|
"bot_description": obj.get("bot_description"),
|
127
|
+
"llm_id": obj.get("llm_id"),
|
128
|
+
"llm_endpoint": LLMEndpointReadInput.from_dict(obj["llm_endpoint"]) if obj.get("llm_endpoint") is not None else None,
|
120
129
|
"query_expansion_prompt": obj.get("query_expansion_prompt"),
|
121
130
|
"show_date_in_sources": obj.get("show_date_in_sources"),
|
122
|
-
"slots_values": obj.get("slots_values"),
|
123
131
|
"selected_aggregations": obj.get("selected_aggregations"),
|
124
132
|
"chat_initial_message": obj.get("chat_initial_message"),
|
125
133
|
"human_takeover": obj.get("human_takeover")
|
@@ -19,6 +19,7 @@ import json
|
|
19
19
|
|
20
20
|
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr
|
21
21
|
from typing import Any, ClassVar, Dict, List, Optional
|
22
|
+
from qanswer_sdk.models.search_metadata_filter import SearchMetadataFilter
|
22
23
|
from typing import Optional, Set
|
23
24
|
from typing_extensions import Self
|
24
25
|
|
@@ -41,7 +42,9 @@ class ChatbotChatPayload(BaseModel):
|
|
41
42
|
oauth_token: Optional[StrictStr] = Field(default=None, description="The oauth token")
|
42
43
|
agentic_chatbot_enabled: Optional[StrictBool] = Field(default=None, description="Whether to enable agentic chatbot")
|
43
44
|
current_time: Optional[StrictStr] = Field(default=None, description="The current time in ISO 8601 format, e.g., 2023-10-05T14:48:00Z")
|
44
|
-
|
45
|
+
auto_filters: Optional[StrictBool] = Field(default=None, description="Determines whether the auto filters should be used for the response.")
|
46
|
+
filters: Optional[List[List[SearchMetadataFilter]]] = None
|
47
|
+
__properties: ClassVar[List[str]] = ["question", "username", "conversation_id", "llm_choice", "image_urls", "parent_message_id", "is_regenerate", "system_message", "addon_system_message", "additional_fields", "bypass_guardrail", "origin", "oauth_token", "agentic_chatbot_enabled", "current_time", "auto_filters", "filters"]
|
45
48
|
|
46
49
|
model_config = ConfigDict(
|
47
50
|
populate_by_name=True,
|
@@ -82,6 +85,15 @@ class ChatbotChatPayload(BaseModel):
|
|
82
85
|
exclude=excluded_fields,
|
83
86
|
exclude_none=True,
|
84
87
|
)
|
88
|
+
# override the default output from pydantic by calling `to_dict()` of each item in filters (list of list)
|
89
|
+
_items = []
|
90
|
+
if self.filters:
|
91
|
+
for _item_filters in self.filters:
|
92
|
+
if _item_filters:
|
93
|
+
_items.append(
|
94
|
+
[_inner_item.to_dict() for _inner_item in _item_filters if _inner_item is not None]
|
95
|
+
)
|
96
|
+
_dict['filters'] = _items
|
85
97
|
return _dict
|
86
98
|
|
87
99
|
@classmethod
|
@@ -108,7 +120,12 @@ class ChatbotChatPayload(BaseModel):
|
|
108
120
|
"origin": obj.get("origin"),
|
109
121
|
"oauth_token": obj.get("oauth_token"),
|
110
122
|
"agentic_chatbot_enabled": obj.get("agentic_chatbot_enabled"),
|
111
|
-
"current_time": obj.get("current_time")
|
123
|
+
"current_time": obj.get("current_time"),
|
124
|
+
"auto_filters": obj.get("auto_filters"),
|
125
|
+
"filters": [
|
126
|
+
[SearchMetadataFilter.from_dict(_inner_item) for _inner_item in _item]
|
127
|
+
for _item in obj["filters"]
|
128
|
+
] if obj.get("filters") is not None else None
|
112
129
|
})
|
113
130
|
return _obj
|
114
131
|
|
@@ -58,6 +58,16 @@ class ChatbotConversationModel(BaseModel):
|
|
58
58
|
raise ValueError("must be one of enum values ('search', 'chat', 'widget', 'microsoft_teams', 'discord', 'slack', 'chatbot_playground', 'undefined')")
|
59
59
|
return value
|
60
60
|
|
61
|
+
@field_validator('shared_entity')
|
62
|
+
def shared_entity_validate_enum(cls, value):
|
63
|
+
"""Validates the enum"""
|
64
|
+
if value is None:
|
65
|
+
return value
|
66
|
+
|
67
|
+
if value not in set(['USER', 'TEAM', 'ORGANIZATION']):
|
68
|
+
raise ValueError("must be one of enum values ('USER', 'TEAM', 'ORGANIZATION')")
|
69
|
+
return value
|
70
|
+
|
61
71
|
model_config = ConfigDict(
|
62
72
|
populate_by_name=True,
|
63
73
|
validate_assignment=True,
|
@@ -19,6 +19,8 @@ import json
|
|
19
19
|
|
20
20
|
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr, field_validator
|
21
21
|
from typing import Any, ClassVar, Dict, List, Optional
|
22
|
+
from qanswer_sdk.models.aggregations_group import AggregationsGroup
|
23
|
+
from qanswer_sdk.models.search_metadata_filter import SearchMetadataFilter
|
22
24
|
from qanswer_sdk.models.source import Source
|
23
25
|
from typing import Optional, Set
|
24
26
|
from typing_extensions import Self
|
@@ -35,7 +37,9 @@ class ChatbotResponse(BaseModel):
|
|
35
37
|
sources: Optional[List[Source]] = Field(default=None, description="The sources used for generation")
|
36
38
|
is_input_data_cropped: Optional[StrictBool] = Field(default=None, description="Indicates whether the input data was cropped during prompting.")
|
37
39
|
mode: Optional[StrictStr] = Field(default=None, description="The mode of the response generation.")
|
38
|
-
|
40
|
+
aggs: Optional[List[AggregationsGroup]] = Field(default=None, description="Aggregations response containing additional metadata or statistics related to the response.")
|
41
|
+
filters: Optional[List[SearchMetadataFilter]] = Field(default=None, description="Filters response containing additional metadata or statistics related to the response.")
|
42
|
+
__properties: ClassVar[List[str]] = ["conversation_id", "message_id", "ai_response", "finish_reason", "is_regenerate", "sources", "is_input_data_cropped", "mode", "aggs", "filters"]
|
39
43
|
|
40
44
|
@field_validator('mode')
|
41
45
|
def mode_validate_enum(cls, value):
|
@@ -93,6 +97,20 @@ class ChatbotResponse(BaseModel):
|
|
93
97
|
if _item_sources:
|
94
98
|
_items.append(_item_sources.to_dict())
|
95
99
|
_dict['sources'] = _items
|
100
|
+
# override the default output from pydantic by calling `to_dict()` of each item in aggs (list)
|
101
|
+
_items = []
|
102
|
+
if self.aggs:
|
103
|
+
for _item_aggs in self.aggs:
|
104
|
+
if _item_aggs:
|
105
|
+
_items.append(_item_aggs.to_dict())
|
106
|
+
_dict['aggs'] = _items
|
107
|
+
# override the default output from pydantic by calling `to_dict()` of each item in filters (list)
|
108
|
+
_items = []
|
109
|
+
if self.filters:
|
110
|
+
for _item_filters in self.filters:
|
111
|
+
if _item_filters:
|
112
|
+
_items.append(_item_filters.to_dict())
|
113
|
+
_dict['filters'] = _items
|
96
114
|
return _dict
|
97
115
|
|
98
116
|
@classmethod
|
@@ -112,7 +130,9 @@ class ChatbotResponse(BaseModel):
|
|
112
130
|
"is_regenerate": obj.get("is_regenerate"),
|
113
131
|
"sources": [Source.from_dict(_item) for _item in obj["sources"]] if obj.get("sources") is not None else None,
|
114
132
|
"is_input_data_cropped": obj.get("is_input_data_cropped"),
|
115
|
-
"mode": obj.get("mode")
|
133
|
+
"mode": obj.get("mode"),
|
134
|
+
"aggs": [AggregationsGroup.from_dict(_item) for _item in obj["aggs"]] if obj.get("aggs") is not None else None,
|
135
|
+
"filters": [SearchMetadataFilter.from_dict(_item) for _item in obj["filters"]] if obj.get("filters") is not None else None
|
116
136
|
})
|
117
137
|
return _obj
|
118
138
|
|
@@ -19,17 +19,18 @@ import json
|
|
19
19
|
|
20
20
|
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr
|
21
21
|
from typing import Any, ClassVar, Dict, List, Optional
|
22
|
+
from qanswer_sdk.models.llm_dto import LlmDto
|
22
23
|
from typing import Optional, Set
|
23
24
|
from typing_extensions import Self
|
24
25
|
|
25
|
-
class
|
26
|
+
class ChatbotSettingDto(BaseModel):
|
26
27
|
"""
|
27
|
-
|
28
|
+
ChatbotSettingDto
|
28
29
|
""" # noqa: E501
|
29
30
|
system_message: Optional[StrictStr] = Field(default=None, alias="systemMessage")
|
30
|
-
llm_choice: Optional[StrictStr] = Field(default=None, alias="llmChoice")
|
31
31
|
agentic_chatbot_enabled: Optional[StrictBool] = Field(default=None, alias="agenticChatbotEnabled")
|
32
|
-
|
32
|
+
llm: Optional[LlmDto] = None
|
33
|
+
__properties: ClassVar[List[str]] = ["systemMessage", "agenticChatbotEnabled", "llm"]
|
33
34
|
|
34
35
|
model_config = ConfigDict(
|
35
36
|
populate_by_name=True,
|
@@ -49,7 +50,7 @@ class UserChatbotSettingPayload(BaseModel):
|
|
49
50
|
|
50
51
|
@classmethod
|
51
52
|
def from_json(cls, json_str: str) -> Optional[Self]:
|
52
|
-
"""Create an instance of
|
53
|
+
"""Create an instance of ChatbotSettingDto from a JSON string"""
|
53
54
|
return cls.from_dict(json.loads(json_str))
|
54
55
|
|
55
56
|
def to_dict(self) -> Dict[str, Any]:
|
@@ -70,16 +71,14 @@ class UserChatbotSettingPayload(BaseModel):
|
|
70
71
|
exclude=excluded_fields,
|
71
72
|
exclude_none=True,
|
72
73
|
)
|
74
|
+
# override the default output from pydantic by calling `to_dict()` of llm
|
75
|
+
if self.llm:
|
76
|
+
_dict['llm'] = self.llm.to_dict()
|
73
77
|
# set to None if system_message (nullable) is None
|
74
78
|
# and model_fields_set contains the field
|
75
79
|
if self.system_message is None and "system_message" in self.model_fields_set:
|
76
80
|
_dict['systemMessage'] = None
|
77
81
|
|
78
|
-
# set to None if llm_choice (nullable) is None
|
79
|
-
# and model_fields_set contains the field
|
80
|
-
if self.llm_choice is None and "llm_choice" in self.model_fields_set:
|
81
|
-
_dict['llmChoice'] = None
|
82
|
-
|
83
82
|
# set to None if agentic_chatbot_enabled (nullable) is None
|
84
83
|
# and model_fields_set contains the field
|
85
84
|
if self.agentic_chatbot_enabled is None and "agentic_chatbot_enabled" in self.model_fields_set:
|
@@ -89,7 +88,7 @@ class UserChatbotSettingPayload(BaseModel):
|
|
89
88
|
|
90
89
|
@classmethod
|
91
90
|
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
92
|
-
"""Create an instance of
|
91
|
+
"""Create an instance of ChatbotSettingDto from a dict"""
|
93
92
|
if obj is None:
|
94
93
|
return None
|
95
94
|
|
@@ -98,8 +97,8 @@ class UserChatbotSettingPayload(BaseModel):
|
|
98
97
|
|
99
98
|
_obj = cls.model_validate({
|
100
99
|
"systemMessage": obj.get("systemMessage"),
|
101
|
-
"
|
102
|
-
"
|
100
|
+
"agenticChatbotEnabled": obj.get("agenticChatbotEnabled"),
|
101
|
+
"llm": LlmDto.from_dict(obj["llm"]) if obj.get("llm") is not None else None
|
103
102
|
})
|
104
103
|
return _obj
|
105
104
|
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
"""
|
4
|
+
QAnswer: Api Documentation
|
5
|
+
|
6
|
+
APIs provided by QAnswer
|
7
|
+
|
8
|
+
The version of the OpenAPI document: 1.0
|
9
|
+
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
10
|
+
|
11
|
+
Do not edit the class manually.
|
12
|
+
""" # noqa: E501
|
13
|
+
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
import pprint
|
17
|
+
import re # noqa: F401
|
18
|
+
import json
|
19
|
+
|
20
|
+
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
|
21
|
+
from typing import Any, ClassVar, Dict, List, Optional
|
22
|
+
from typing import Optional, Set
|
23
|
+
from typing_extensions import Self
|
24
|
+
|
25
|
+
class ChatbotSettingRequest(BaseModel):
|
26
|
+
"""
|
27
|
+
ChatbotSettingRequest
|
28
|
+
""" # noqa: E501
|
29
|
+
system_message: Optional[StrictStr] = Field(default=None, alias="systemMessage")
|
30
|
+
llm_id: Optional[StrictInt] = Field(default=None, alias="llmId")
|
31
|
+
agentic_chatbot_enabled: Optional[StrictBool] = Field(default=None, alias="agenticChatbotEnabled")
|
32
|
+
__properties: ClassVar[List[str]] = ["systemMessage", "llmId", "agenticChatbotEnabled"]
|
33
|
+
|
34
|
+
model_config = ConfigDict(
|
35
|
+
populate_by_name=True,
|
36
|
+
validate_assignment=True,
|
37
|
+
protected_namespaces=(),
|
38
|
+
)
|
39
|
+
|
40
|
+
|
41
|
+
def to_str(self) -> str:
|
42
|
+
"""Returns the string representation of the model using alias"""
|
43
|
+
return pprint.pformat(self.model_dump(by_alias=True))
|
44
|
+
|
45
|
+
def to_json(self) -> str:
|
46
|
+
"""Returns the JSON representation of the model using alias"""
|
47
|
+
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
48
|
+
return json.dumps(self.to_dict())
|
49
|
+
|
50
|
+
@classmethod
|
51
|
+
def from_json(cls, json_str: str) -> Optional[Self]:
|
52
|
+
"""Create an instance of ChatbotSettingRequest from a JSON string"""
|
53
|
+
return cls.from_dict(json.loads(json_str))
|
54
|
+
|
55
|
+
def to_dict(self) -> Dict[str, Any]:
|
56
|
+
"""Return the dictionary representation of the model using alias.
|
57
|
+
|
58
|
+
This has the following differences from calling pydantic's
|
59
|
+
`self.model_dump(by_alias=True)`:
|
60
|
+
|
61
|
+
* `None` is only added to the output dict for nullable fields that
|
62
|
+
were set at model initialization. Other fields with value `None`
|
63
|
+
are ignored.
|
64
|
+
"""
|
65
|
+
excluded_fields: Set[str] = set([
|
66
|
+
])
|
67
|
+
|
68
|
+
_dict = self.model_dump(
|
69
|
+
by_alias=True,
|
70
|
+
exclude=excluded_fields,
|
71
|
+
exclude_none=True,
|
72
|
+
)
|
73
|
+
# set to None if llm_id (nullable) is None
|
74
|
+
# and model_fields_set contains the field
|
75
|
+
if self.llm_id is None and "llm_id" in self.model_fields_set:
|
76
|
+
_dict['llmId'] = None
|
77
|
+
|
78
|
+
return _dict
|
79
|
+
|
80
|
+
@classmethod
|
81
|
+
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
82
|
+
"""Create an instance of ChatbotSettingRequest from a dict"""
|
83
|
+
if obj is None:
|
84
|
+
return None
|
85
|
+
|
86
|
+
if not isinstance(obj, dict):
|
87
|
+
return cls.model_validate(obj)
|
88
|
+
|
89
|
+
_obj = cls.model_validate({
|
90
|
+
"systemMessage": obj.get("systemMessage"),
|
91
|
+
"llmId": obj.get("llmId"),
|
92
|
+
"agenticChatbotEnabled": obj.get("agenticChatbotEnabled")
|
93
|
+
})
|
94
|
+
return _obj
|
95
|
+
|
96
|
+
|
@@ -22,13 +22,13 @@ from typing import Any, ClassVar, Dict, List
|
|
22
22
|
from typing import Optional, Set
|
23
23
|
from typing_extensions import Self
|
24
24
|
|
25
|
-
class
|
25
|
+
class ClipConnectorFileStructure(BaseModel):
|
26
26
|
"""
|
27
|
-
|
27
|
+
ClipConnectorFileStructure
|
28
28
|
""" # noqa: E501
|
29
|
-
|
30
|
-
|
31
|
-
__properties: ClassVar[List[str]] = ["
|
29
|
+
file_id: StrictStr
|
30
|
+
display_name: StrictStr
|
31
|
+
__properties: ClassVar[List[str]] = ["file_id", "display_name"]
|
32
32
|
|
33
33
|
model_config = ConfigDict(
|
34
34
|
populate_by_name=True,
|
@@ -48,7 +48,7 @@ class QuestionCompletion(BaseModel):
|
|
48
48
|
|
49
49
|
@classmethod
|
50
50
|
def from_json(cls, json_str: str) -> Optional[Self]:
|
51
|
-
"""Create an instance of
|
51
|
+
"""Create an instance of ClipConnectorFileStructure from a JSON string"""
|
52
52
|
return cls.from_dict(json.loads(json_str))
|
53
53
|
|
54
54
|
def to_dict(self) -> Dict[str, Any]:
|
@@ -73,7 +73,7 @@ class QuestionCompletion(BaseModel):
|
|
73
73
|
|
74
74
|
@classmethod
|
75
75
|
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
76
|
-
"""Create an instance of
|
76
|
+
"""Create an instance of ClipConnectorFileStructure from a dict"""
|
77
77
|
if obj is None:
|
78
78
|
return None
|
79
79
|
|
@@ -81,8 +81,8 @@ class QuestionCompletion(BaseModel):
|
|
81
81
|
return cls.model_validate(obj)
|
82
82
|
|
83
83
|
_obj = cls.model_validate({
|
84
|
-
"
|
85
|
-
"
|
84
|
+
"file_id": obj.get("file_id"),
|
85
|
+
"display_name": obj.get("display_name")
|
86
86
|
})
|
87
87
|
return _obj
|
88
88
|
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
"""
|
4
|
+
QAnswer: Api Documentation
|
5
|
+
|
6
|
+
APIs provided by QAnswer
|
7
|
+
|
8
|
+
The version of the OpenAPI document: 1.0
|
9
|
+
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
10
|
+
|
11
|
+
Do not edit the class manually.
|
12
|
+
""" # noqa: E501
|
13
|
+
|
14
|
+
|
15
|
+
from __future__ import annotations
|
16
|
+
import pprint
|
17
|
+
import re # noqa: F401
|
18
|
+
import json
|
19
|
+
|
20
|
+
from pydantic import BaseModel, ConfigDict, StrictInt
|
21
|
+
from typing import Any, ClassVar, Dict, List
|
22
|
+
from qanswer_sdk.models.clip_connector_file_structure import ClipConnectorFileStructure
|
23
|
+
from typing import Optional, Set
|
24
|
+
from typing_extensions import Self
|
25
|
+
|
26
|
+
class ClipConnectorStructure(BaseModel):
|
27
|
+
"""
|
28
|
+
ClipConnectorStructure
|
29
|
+
""" # noqa: E501
|
30
|
+
connector_id: StrictInt
|
31
|
+
files_required: List[ClipConnectorFileStructure]
|
32
|
+
__properties: ClassVar[List[str]] = ["connector_id", "files_required"]
|
33
|
+
|
34
|
+
model_config = ConfigDict(
|
35
|
+
populate_by_name=True,
|
36
|
+
validate_assignment=True,
|
37
|
+
protected_namespaces=(),
|
38
|
+
)
|
39
|
+
|
40
|
+
|
41
|
+
def to_str(self) -> str:
|
42
|
+
"""Returns the string representation of the model using alias"""
|
43
|
+
return pprint.pformat(self.model_dump(by_alias=True))
|
44
|
+
|
45
|
+
def to_json(self) -> str:
|
46
|
+
"""Returns the JSON representation of the model using alias"""
|
47
|
+
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
48
|
+
return json.dumps(self.to_dict())
|
49
|
+
|
50
|
+
@classmethod
|
51
|
+
def from_json(cls, json_str: str) -> Optional[Self]:
|
52
|
+
"""Create an instance of ClipConnectorStructure from a JSON string"""
|
53
|
+
return cls.from_dict(json.loads(json_str))
|
54
|
+
|
55
|
+
def to_dict(self) -> Dict[str, Any]:
|
56
|
+
"""Return the dictionary representation of the model using alias.
|
57
|
+
|
58
|
+
This has the following differences from calling pydantic's
|
59
|
+
`self.model_dump(by_alias=True)`:
|
60
|
+
|
61
|
+
* `None` is only added to the output dict for nullable fields that
|
62
|
+
were set at model initialization. Other fields with value `None`
|
63
|
+
are ignored.
|
64
|
+
"""
|
65
|
+
excluded_fields: Set[str] = set([
|
66
|
+
])
|
67
|
+
|
68
|
+
_dict = self.model_dump(
|
69
|
+
by_alias=True,
|
70
|
+
exclude=excluded_fields,
|
71
|
+
exclude_none=True,
|
72
|
+
)
|
73
|
+
# override the default output from pydantic by calling `to_dict()` of each item in files_required (list)
|
74
|
+
_items = []
|
75
|
+
if self.files_required:
|
76
|
+
for _item_files_required in self.files_required:
|
77
|
+
if _item_files_required:
|
78
|
+
_items.append(_item_files_required.to_dict())
|
79
|
+
_dict['files_required'] = _items
|
80
|
+
return _dict
|
81
|
+
|
82
|
+
@classmethod
|
83
|
+
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
84
|
+
"""Create an instance of ClipConnectorStructure from a dict"""
|
85
|
+
if obj is None:
|
86
|
+
return None
|
87
|
+
|
88
|
+
if not isinstance(obj, dict):
|
89
|
+
return cls.model_validate(obj)
|
90
|
+
|
91
|
+
_obj = cls.model_validate({
|
92
|
+
"connector_id": obj.get("connector_id"),
|
93
|
+
"files_required": [ClipConnectorFileStructure.from_dict(_item) for _item in obj["files_required"]] if obj.get("files_required") is not None else None
|
94
|
+
})
|
95
|
+
return _obj
|
96
|
+
|
97
|
+
|
@@ -41,8 +41,8 @@ class ConnectorModel(BaseModel):
|
|
41
41
|
@field_validator('connector_type')
|
42
42
|
def connector_type_validate_enum(cls, value):
|
43
43
|
"""Validates the enum"""
|
44
|
-
if value not in set(['document', 'website', 'qna', 'pinecone', 'rdf', 'websearch', 'econsilium', 'econsilium_search_index', 'publication_office', 'onedrive', 'sharepoint', 'gdrive', 'onenote']):
|
45
|
-
raise ValueError("must be one of enum values ('document', 'website', 'qna', 'pinecone', 'rdf', 'websearch', 'econsilium', 'econsilium_search_index', 'publication_office', 'onedrive', 'sharepoint', 'gdrive', 'onenote')")
|
44
|
+
if value not in set(['document', 'website', 'qna', 'pinecone', 'rdf', 'websearch', 'econsilium', 'econsilium_search_index', 'publication_office', 'onedrive', 'sharepoint', 'gdrive', 'onenote', 'imap']):
|
45
|
+
raise ValueError("must be one of enum values ('document', 'website', 'qna', 'pinecone', 'rdf', 'websearch', 'econsilium', 'econsilium_search_index', 'publication_office', 'onedrive', 'sharepoint', 'gdrive', 'onenote', 'imap')")
|
46
46
|
return value
|
47
47
|
|
48
48
|
model_config = ConfigDict(
|
@@ -21,7 +21,6 @@ from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, Strict
|
|
21
21
|
from typing import Any, ClassVar, Dict, List, Optional
|
22
22
|
from qanswer_sdk.models.aggregations_group import AggregationsGroup
|
23
23
|
from qanswer_sdk.models.content_item import ContentItem
|
24
|
-
from qanswer_sdk.models.question_completion import QuestionCompletion
|
25
24
|
from qanswer_sdk.models.source import Source
|
26
25
|
from typing import Optional, Set
|
27
26
|
from typing_extensions import Self
|
@@ -43,13 +42,13 @@ class ConversationMessage(BaseModel):
|
|
43
42
|
interface_origin: Optional[StrictStr] = None
|
44
43
|
comment: Optional[StrictStr] = None
|
45
44
|
llm_choice: Optional[StrictStr] = None
|
46
|
-
training_examples: Optional[List[QuestionCompletion]] = None
|
47
45
|
prompt_used: Optional[StrictStr] = None
|
48
46
|
mode: Optional[StrictStr] = None
|
49
47
|
is_input_data_cropped: Optional[StrictBool] = None
|
50
48
|
aggs: Optional[List[AggregationsGroup]] = None
|
51
49
|
expanded_question: Optional[StrictStr] = None
|
52
|
-
|
50
|
+
prompt_type: Optional[StrictStr] = None
|
51
|
+
__properties: ClassVar[List[str]] = ["role", "contents", "message_id", "parent_message_id", "timestamp", "feedback", "origin", "sources", "all_sources", "task_category", "interface_origin", "comment", "llm_choice", "prompt_used", "mode", "is_input_data_cropped", "aggs", "expanded_question", "prompt_type"]
|
53
52
|
|
54
53
|
@field_validator('role')
|
55
54
|
def role_validate_enum(cls, value):
|
@@ -135,13 +134,6 @@ class ConversationMessage(BaseModel):
|
|
135
134
|
if _item_all_sources:
|
136
135
|
_items.append(_item_all_sources.to_dict())
|
137
136
|
_dict['all_sources'] = _items
|
138
|
-
# override the default output from pydantic by calling `to_dict()` of each item in training_examples (list)
|
139
|
-
_items = []
|
140
|
-
if self.training_examples:
|
141
|
-
for _item_training_examples in self.training_examples:
|
142
|
-
if _item_training_examples:
|
143
|
-
_items.append(_item_training_examples.to_dict())
|
144
|
-
_dict['training_examples'] = _items
|
145
137
|
# override the default output from pydantic by calling `to_dict()` of each item in aggs (list)
|
146
138
|
_items = []
|
147
139
|
if self.aggs:
|
@@ -174,12 +166,12 @@ class ConversationMessage(BaseModel):
|
|
174
166
|
"interface_origin": obj.get("interface_origin"),
|
175
167
|
"comment": obj.get("comment"),
|
176
168
|
"llm_choice": obj.get("llm_choice"),
|
177
|
-
"training_examples": [QuestionCompletion.from_dict(_item) for _item in obj["training_examples"]] if obj.get("training_examples") is not None else None,
|
178
169
|
"prompt_used": obj.get("prompt_used"),
|
179
170
|
"mode": obj.get("mode"),
|
180
171
|
"is_input_data_cropped": obj.get("is_input_data_cropped"),
|
181
172
|
"aggs": [AggregationsGroup.from_dict(_item) for _item in obj["aggs"]] if obj.get("aggs") is not None else None,
|
182
|
-
"expanded_question": obj.get("expanded_question")
|
173
|
+
"expanded_question": obj.get("expanded_question"),
|
174
|
+
"prompt_type": obj.get("prompt_type")
|
183
175
|
})
|
184
176
|
return _obj
|
185
177
|
|