letschatty 0.4.349__py3-none-any.whl → 0.4.351__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of letschatty might be problematic. Click here for more details.
- letschatty/models/ai_microservices/__init__.py +4 -4
- letschatty/models/ai_microservices/expected_output.py +29 -2
- letschatty/models/ai_microservices/lambda_events.py +155 -28
- letschatty/models/ai_microservices/lambda_invokation_types.py +4 -1
- letschatty/models/ai_microservices/n8n_ai_agents_payload.py +3 -1
- letschatty/models/analytics/events/__init__.py +3 -3
- letschatty/models/analytics/events/chat_based_events/ai_agent_execution_event.py +71 -0
- letschatty/models/analytics/events/chat_based_events/chat_funnel.py +13 -69
- letschatty/models/analytics/events/company_based_events/asset_events.py +2 -9
- letschatty/models/analytics/events/event_type_to_classes.py +3 -7
- letschatty/models/analytics/events/event_types.py +50 -11
- letschatty/models/chat/chat.py +2 -13
- letschatty/models/chat/chat_with_assets.py +1 -6
- letschatty/models/chat/client.py +2 -0
- letschatty/models/chat/continuous_conversation.py +1 -1
- letschatty/models/company/CRM/funnel.py +33 -365
- letschatty/models/company/__init__.py +1 -7
- letschatty/models/company/assets/ai_agents_v2/ai_agents_decision_output.py +1 -1
- letschatty/models/company/assets/ai_agents_v2/chatty_ai_agent_in_chat.py +4 -0
- letschatty/models/company/assets/ai_agents_v2/chatty_ai_mode.py +2 -2
- letschatty/models/company/assets/ai_agents_v2/get_chat_with_prompt_response.py +1 -0
- letschatty/models/company/assets/ai_agents_v2/pre_qualify_config.py +28 -1
- letschatty/models/company/assets/automation.py +19 -10
- letschatty/models/company/assets/chat_assets.py +2 -3
- letschatty/models/company/assets/company_assets.py +0 -2
- letschatty/models/company/assets/sale.py +3 -3
- letschatty/models/company/empresa.py +1 -2
- letschatty/models/data_base/collection_interface.py +101 -29
- letschatty/models/data_base/mongo_connection.py +92 -9
- letschatty/models/messages/chatty_messages/schema/chatty_content/content_document.py +2 -4
- letschatty/models/messages/chatty_messages/schema/chatty_content/content_media.py +3 -4
- letschatty/models/utils/custom_exceptions/custom_exceptions.py +14 -1
- letschatty/services/ai_agents/smart_follow_up_context_builder_v2.py +5 -2
- letschatty/services/chat/chat_service.py +11 -47
- letschatty/services/chatty_assets/__init__.py +12 -0
- letschatty/services/chatty_assets/asset_service.py +190 -13
- letschatty/services/chatty_assets/assets_collections.py +137 -0
- letschatty/services/chatty_assets/base_container.py +3 -2
- letschatty/services/chatty_assets/base_container_with_collection.py +35 -26
- letschatty/services/chatty_assets/collections/__init__.py +38 -0
- letschatty/services/chatty_assets/collections/ai_agent_collection.py +19 -0
- letschatty/services/chatty_assets/collections/ai_agent_in_chat_collection.py +32 -0
- letschatty/services/chatty_assets/collections/ai_component_collection.py +21 -0
- letschatty/services/chatty_assets/collections/chain_of_thought_collection.py +30 -0
- letschatty/services/chatty_assets/collections/chat_collection.py +21 -0
- letschatty/services/chatty_assets/collections/contact_point_collection.py +21 -0
- letschatty/services/chatty_assets/collections/fast_answer_collection.py +21 -0
- letschatty/services/chatty_assets/collections/filter_criteria_collection.py +18 -0
- letschatty/services/chatty_assets/collections/flow_collection.py +20 -0
- letschatty/services/chatty_assets/collections/product_collection.py +20 -0
- letschatty/services/chatty_assets/collections/sale_collection.py +20 -0
- letschatty/services/chatty_assets/collections/source_collection.py +21 -0
- letschatty/services/chatty_assets/collections/tag_collection.py +19 -0
- letschatty/services/chatty_assets/collections/topic_collection.py +21 -0
- letschatty/services/chatty_assets/collections/user_collection.py +20 -0
- letschatty/services/chatty_assets/example_usage.py +44 -0
- letschatty/services/chatty_assets/services/__init__.py +37 -0
- letschatty/services/chatty_assets/services/ai_agent_in_chat_service.py +73 -0
- letschatty/services/chatty_assets/services/ai_agent_service.py +23 -0
- letschatty/services/chatty_assets/services/chain_of_thought_service.py +70 -0
- letschatty/services/chatty_assets/services/chat_service.py +25 -0
- letschatty/services/chatty_assets/services/contact_point_service.py +29 -0
- letschatty/services/chatty_assets/services/fast_answer_service.py +32 -0
- letschatty/services/chatty_assets/services/filter_criteria_service.py +30 -0
- letschatty/services/chatty_assets/services/flow_service.py +25 -0
- letschatty/services/chatty_assets/services/product_service.py +30 -0
- letschatty/services/chatty_assets/services/sale_service.py +25 -0
- letschatty/services/chatty_assets/services/source_service.py +28 -0
- letschatty/services/chatty_assets/services/tag_service.py +32 -0
- letschatty/services/chatty_assets/services/topic_service.py +31 -0
- letschatty/services/chatty_assets/services/user_service.py +32 -0
- letschatty/services/continuous_conversation_service/continuous_conversation_helper.py +11 -0
- letschatty/services/events/__init__.py +6 -0
- letschatty/services/events/events_manager.py +218 -1
- letschatty/services/factories/analytics/ai_agent_event_factory.py +161 -0
- letschatty/services/factories/analytics/events_factory.py +66 -30
- letschatty/services/factories/lambda_ai_orchestrartor/lambda_events_factory.py +46 -8
- letschatty/services/messages_helpers/get_caption_or_body_or_preview.py +6 -4
- letschatty/services/validators/analytics_validator.py +0 -11
- {letschatty-0.4.349.dist-info → letschatty-0.4.351.dist-info}/METADATA +1 -1
- {letschatty-0.4.349.dist-info → letschatty-0.4.351.dist-info}/RECORD +83 -53
- letschatty/models/analytics/events/chat_based_events/chat_client.py +0 -19
- letschatty/models/company/integrations/product_sync_status.py +0 -28
- letschatty/models/company/integrations/shopify/company_shopify_integration.py +0 -62
- letschatty/models/company/integrations/shopify/shopify_product_sync_status.py +0 -18
- letschatty/models/company/integrations/shopify/shopify_webhook_topics.py +0 -40
- letschatty/models/company/integrations/sync_status_enum.py +0 -9
- {letschatty-0.4.349.dist-info → letschatty-0.4.351.dist-info}/LICENSE +0 -0
- {letschatty-0.4.349.dist-info → letschatty-0.4.351.dist-info}/WHEEL +0 -0
|
@@ -64,7 +64,8 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
64
64
|
self.update_previews_thread()
|
|
65
65
|
self.load_from_db_thread(company_id=None)
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
# All methods are now async-only for better performance
|
|
68
|
+
async def insert(self, item: T, execution_context: ExecutionContext) -> T:
|
|
68
69
|
"""
|
|
69
70
|
Add an item to the container and insert it into the database collection.
|
|
70
71
|
|
|
@@ -77,12 +78,12 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
77
78
|
"""
|
|
78
79
|
logger.debug(f"{self.__class__.__name__} inserting item {item}")
|
|
79
80
|
inserted_item = super().insert(item)
|
|
80
|
-
self.collection.insert(inserted_item)
|
|
81
|
+
await self.collection.insert(inserted_item)
|
|
81
82
|
execution_context.set_event_time(inserted_item.created_at)
|
|
82
83
|
self.update_previews_thread()
|
|
83
84
|
return inserted_item
|
|
84
85
|
|
|
85
|
-
def update(self, id: str, new_item: T, execution_context: ExecutionContext) -> T:
|
|
86
|
+
async def update(self, id: str, new_item: T, execution_context: ExecutionContext) -> T:
|
|
86
87
|
"""
|
|
87
88
|
Update an item in the container and in the database collection.
|
|
88
89
|
|
|
@@ -105,18 +106,18 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
105
106
|
if id != updated_item.id:
|
|
106
107
|
logger.error(f"Item id {id} does not match updated item id {updated_item.id}")
|
|
107
108
|
raise ValueError(f"Item id {id} does not match updated item id {updated_item.id}")
|
|
108
|
-
self.collection.update(updated_item)
|
|
109
|
+
await self.collection.update(updated_item)
|
|
109
110
|
execution_context.set_event_time(updated_item.updated_at)
|
|
110
111
|
self.update_preview(updated_item)
|
|
111
112
|
self.update_previews_thread()
|
|
112
113
|
return updated_item
|
|
113
114
|
|
|
114
115
|
except NotFoundError as e:
|
|
115
|
-
outdated_item = self.collection.get_by_id(id)
|
|
116
|
+
outdated_item = await self.collection.get_by_id(id)
|
|
116
117
|
if outdated_item:
|
|
117
118
|
updated_item = outdated_item.update(new_item)
|
|
118
119
|
self.items[id] = updated_item
|
|
119
|
-
self.collection.update(updated_item)
|
|
120
|
+
await self.collection.update(updated_item)
|
|
120
121
|
execution_context.set_event_time(updated_item.updated_at)
|
|
121
122
|
self.update_previews_thread()
|
|
122
123
|
return updated_item
|
|
@@ -125,7 +126,7 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
125
126
|
f"Item with id {id} not found in {self.__class__.__name__} nor in collection DB"
|
|
126
127
|
)
|
|
127
128
|
|
|
128
|
-
def delete(self, id: str, execution_context: ExecutionContext,deletion_type : DeletionType = DeletionType.LOGICAL) -> T:
|
|
129
|
+
async def delete(self, id: str, execution_context: ExecutionContext,deletion_type : DeletionType = DeletionType.LOGICAL) -> T:
|
|
129
130
|
"""
|
|
130
131
|
Delete an item from the container and the collection.
|
|
131
132
|
|
|
@@ -142,16 +143,16 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
142
143
|
deleted_item = super().delete(id)
|
|
143
144
|
self.delete_preview(id)
|
|
144
145
|
execution_context.set_event_time(datetime.now(ZoneInfo("UTC")))
|
|
145
|
-
self.collection.delete(id, deletion_type)
|
|
146
|
+
await self.collection.delete(id, deletion_type)
|
|
146
147
|
return deleted_item
|
|
147
148
|
except NotFoundError as e:
|
|
148
|
-
self.collection.delete(id, deletion_type)
|
|
149
|
+
await self.collection.delete(id, deletion_type)
|
|
149
150
|
self.delete_preview(id)
|
|
150
151
|
self.update_previews_thread()
|
|
151
152
|
execution_context.set_event_time(datetime.now(ZoneInfo("UTC")))
|
|
152
|
-
return self.collection.get_by_id(id)
|
|
153
|
+
return await self.collection.get_by_id(id)
|
|
153
154
|
|
|
154
|
-
def get_by_id(self, id: str) -> T:
|
|
155
|
+
async def get_by_id(self, id: str) -> T:
|
|
155
156
|
"""
|
|
156
157
|
Get an item from the container.
|
|
157
158
|
|
|
@@ -174,7 +175,7 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
174
175
|
# #if they are supposed to be in memory, we raise an error since it shouldn't be in the collection DB
|
|
175
176
|
# raise NotFoundError(f"Item with id {id} not found in {self.__class__.__name__} nor in collection DB")
|
|
176
177
|
logger.debug(f"{self.__class__.__name__} getting item {id} not found in container, trying to get from collection")
|
|
177
|
-
item = self.collection.get_by_id(id)
|
|
178
|
+
item = await self.collection.get_by_id(id)
|
|
178
179
|
if item:
|
|
179
180
|
if item.deleted_at is not None:
|
|
180
181
|
return item
|
|
@@ -239,7 +240,7 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
239
240
|
logger.debug(f"Clearing previews cache of {self.__class__.__name__}")
|
|
240
241
|
self.set_preview_items([])
|
|
241
242
|
|
|
242
|
-
def get_all(self, company_id: Optional[StrObjectId]) -> List[T]:
|
|
243
|
+
async def get_all(self, company_id: Optional[StrObjectId]) -> List[T]:
|
|
243
244
|
# Get items from memory
|
|
244
245
|
logger.debug(f"{self.__class__.__name__} getting all items from memory and collection")
|
|
245
246
|
memory_items = super().get_all(company_id=company_id)
|
|
@@ -247,7 +248,7 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
247
248
|
memory_ids = [ObjectId(item.id) for item in memory_items]
|
|
248
249
|
# Build the query for collection items
|
|
249
250
|
query = {"deleted_at": None, "_id": {"$nin": memory_ids}}
|
|
250
|
-
collection_items = self.collection.get_docs(query=query, company_id=company_id)
|
|
251
|
+
collection_items = await self.collection.get_docs(query=query, company_id=company_id)
|
|
251
252
|
all_items = memory_items + collection_items
|
|
252
253
|
return sorted(all_items, key=lambda x: x.created_at, reverse=True)
|
|
253
254
|
|
|
@@ -261,6 +262,8 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
261
262
|
def update_previews_thread(self):
|
|
262
263
|
"""We start a thread to update the previews cache so it doesn't block the main thread"""
|
|
263
264
|
# self.update_previews_cache()
|
|
265
|
+
if not self.cache_config.keep_previews_always_in_memory:
|
|
266
|
+
return
|
|
264
267
|
thread = threading.Thread(target=self.update_previews_cache)
|
|
265
268
|
thread.start()
|
|
266
269
|
|
|
@@ -275,13 +278,13 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
275
278
|
self.set_preview_items(collection_items)
|
|
276
279
|
return collection_items
|
|
277
280
|
|
|
278
|
-
def get_by_query(self, query: dict, company_id: Optional[StrObjectId]) -> List[T]:
|
|
281
|
+
async def get_by_query(self, query: dict, company_id: Optional[StrObjectId]) -> List[T]:
|
|
279
282
|
logger.debug(f"{self.__class__.__name__} getting items by query {query} from collection")
|
|
280
|
-
return self.collection.get_docs(query=query, company_id=company_id)
|
|
283
|
+
return await self.collection.get_docs(query=query, company_id=company_id)
|
|
281
284
|
|
|
282
|
-
def get_deleted(self, company_id: Optional[StrObjectId]) -> List[T]:
|
|
285
|
+
async def get_deleted(self, company_id: Optional[StrObjectId]) -> List[T]:
|
|
283
286
|
logger.debug(f"{self.__class__.__name__} getting deleted items from collection")
|
|
284
|
-
return self.collection.get_docs(query={"deleted_at": {"$ne": None}}, company_id=company_id)
|
|
287
|
+
return await self.collection.get_docs(query={"deleted_at": {"$ne": None}}, company_id=company_id)
|
|
285
288
|
|
|
286
289
|
def load_from_db_thread(self, company_id: Optional[StrObjectId]):
|
|
287
290
|
"""We start a thread to load the items from the database so it doesn't block the main thread"""
|
|
@@ -292,21 +295,27 @@ class ChattyAssetContainerWithCollection(ChattyAssetBaseContainer[T, P], ABC):
|
|
|
292
295
|
thread.start()
|
|
293
296
|
|
|
294
297
|
def load_from_db(self, company_id: Optional[StrObjectId]):
|
|
295
|
-
"""Pass company_id=None to load all items from the database."""
|
|
298
|
+
"""Pass company_id=None to load all items from the database. Uses sync client for background loading."""
|
|
296
299
|
logger.debug(f"{self.__class__.__name__} loading items from collection")
|
|
297
|
-
#
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
300
|
+
# Background loading uses sync client (less critical, runs in thread)
|
|
301
|
+
query: Dict[str, Any] = {"deleted_at": None}
|
|
302
|
+
if company_id:
|
|
303
|
+
query["company_id"] = company_id
|
|
304
|
+
docs = list(self.collection.collection.find(filter=query))
|
|
305
|
+
# Create instances once and reuse
|
|
306
|
+
loaded_items = [self.collection.create_instance(doc) for doc in docs]
|
|
307
|
+
self.items = {item.id: item for item in loaded_items}
|
|
308
|
+
|
|
309
|
+
async def restore(self, id: str, execution_context: ExecutionContext) -> T:
|
|
301
310
|
logger.debug(f"{self.__class__.__name__} restoring item {id} with execution context {execution_context}")
|
|
302
311
|
if id in self.items:
|
|
303
312
|
raise ValueError(f"Item with id {id} already exists in {self.__class__.__name__}")
|
|
304
|
-
restored_item = self.collection.get_by_id(id)
|
|
313
|
+
restored_item = await self.collection.get_by_id(id)
|
|
305
314
|
if restored_item is None:
|
|
306
315
|
raise NotFoundError(f"Item with id {id} not found in collection DB")
|
|
307
316
|
restored_item.deleted_at = None
|
|
308
317
|
restored_item.update_now()
|
|
309
318
|
execution_context.set_event_time(restored_item.updated_at)
|
|
310
319
|
self.items[id] = restored_item
|
|
311
|
-
self.collection.update(restored_item)
|
|
312
|
-
return restored_item
|
|
320
|
+
await self.collection.update(restored_item)
|
|
321
|
+
return restored_item
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Asset Collection Subclasses
|
|
3
|
+
|
|
4
|
+
This module provides pre-configured AssetCollection subclasses for each asset type.
|
|
5
|
+
These ensure consistency between the API and microservices by defining the collection
|
|
6
|
+
configuration (collection name, asset type, preview type, create_instance_method) once.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from .product_collection import ProductCollection
|
|
10
|
+
from .tag_collection import TagCollection
|
|
11
|
+
from .user_collection import UserCollection
|
|
12
|
+
from .chat_collection import ChatCollection
|
|
13
|
+
from .source_collection import SourceCollection
|
|
14
|
+
from .flow_collection import FlowCollection
|
|
15
|
+
from .sale_collection import SaleCollection
|
|
16
|
+
from .contact_point_collection import ContactPointCollection
|
|
17
|
+
from .ai_agent_collection import AiAgentCollection
|
|
18
|
+
from .fast_answer_collection import FastAnswerCollection
|
|
19
|
+
from .topic_collection import TopicCollection
|
|
20
|
+
from .filter_criteria_collection import FilterCriteriaCollection
|
|
21
|
+
from .ai_component_collection import AiComponentCollection
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
'ProductCollection',
|
|
25
|
+
'TagCollection',
|
|
26
|
+
'UserCollection',
|
|
27
|
+
'ChatCollection',
|
|
28
|
+
'SourceCollection',
|
|
29
|
+
'FlowCollection',
|
|
30
|
+
'SaleCollection',
|
|
31
|
+
'ContactPointCollection',
|
|
32
|
+
'AiAgentCollection',
|
|
33
|
+
'FastAnswerCollection',
|
|
34
|
+
'TopicCollection',
|
|
35
|
+
'FilterCriteriaCollection',
|
|
36
|
+
'AiComponentCollection',
|
|
37
|
+
]
|
|
38
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""AI Agent Collection - Pre-configured AssetCollection for AI Agents"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets.ai_agents_v2.chatty_ai_agent import ChattyAIAgent, ChattyAIAgentPreview
|
|
5
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AiAgentCollection(AssetCollection[ChattyAIAgent, ChattyAIAgentPreview]):
|
|
9
|
+
"""Pre-configured collection for AI Agent assets"""
|
|
10
|
+
|
|
11
|
+
def __init__(self, connection: MongoConnection):
|
|
12
|
+
super().__init__(
|
|
13
|
+
collection="ai_agents",
|
|
14
|
+
asset_type=ChattyAIAgent,
|
|
15
|
+
connection=connection,
|
|
16
|
+
create_instance_method=ChattyAIAgent.default_create_instance_method,
|
|
17
|
+
preview_type=ChattyAIAgentPreview
|
|
18
|
+
)
|
|
19
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""AI Agent In Chat Collection - Pre-configured AssetCollection for AI Agent state in chats"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets.ai_agents_v2.chatty_ai_agent_in_chat import ChattyAIAgentInChat
|
|
5
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AIAgentInChatCollection(AssetCollection[ChattyAIAgentInChat, ChattyAIAgentInChat]):
|
|
10
|
+
"""
|
|
11
|
+
Pre-configured collection for AI Agent In Chat state.
|
|
12
|
+
|
|
13
|
+
This is a standalone collection (not embedded in Chat) that allows Lambda to
|
|
14
|
+
manage AI agent state independently without loading entire chat documents.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, connection: MongoConnection):
|
|
18
|
+
super().__init__(
|
|
19
|
+
collection="chatty_ai_agents_in_chat",
|
|
20
|
+
asset_type=ChattyAIAgentInChat,
|
|
21
|
+
connection=connection,
|
|
22
|
+
create_instance_method=lambda doc: ChattyAIAgentInChat(**doc),
|
|
23
|
+
preview_type=ChattyAIAgentInChat # No separate preview type needed
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
async def get_by_chat_id(self, chat_id: str) -> Optional[ChattyAIAgentInChat]:
|
|
27
|
+
"""Get AI agent state by chat ID, or None if not found"""
|
|
28
|
+
doc = await self.async_collection.find_one({"chat_id": chat_id, "deleted_at": None})
|
|
29
|
+
if not doc:
|
|
30
|
+
return None
|
|
31
|
+
return self.create_instance(doc)
|
|
32
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""AI Component Collection - Pre-configured AssetCollection for AI Components"""
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from ..asset_service import AssetCollection
|
|
5
|
+
from ....models.base_models.ai_agent_component import AiAgentComponent, AiAgentComponentPreview
|
|
6
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
7
|
+
from ....services.ai_components_service import AiComponentsService
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AiComponentCollection(AssetCollection[AiAgentComponent, AiAgentComponentPreview]):
|
|
11
|
+
"""Pre-configured collection for AI Component assets"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, connection: MongoConnection):
|
|
14
|
+
super().__init__(
|
|
15
|
+
collection="ai_components",
|
|
16
|
+
asset_type=AiAgentComponent,
|
|
17
|
+
connection=connection,
|
|
18
|
+
create_instance_method=AiComponentsService.instantiate_component,
|
|
19
|
+
preview_type=AiAgentComponentPreview
|
|
20
|
+
)
|
|
21
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Chain of Thought Collection - Pre-configured AssetCollection for Chain of Thoughts"""
|
|
2
|
+
|
|
3
|
+
from typing import Any, List, Dict
|
|
4
|
+
|
|
5
|
+
from letschatty.models.utils.types.serializer_type import SerializerType
|
|
6
|
+
from ..asset_service import AssetCollection, StrObjectId
|
|
7
|
+
from ....models.company.assets.ai_agents_v2.chain_of_thought_in_chat import (
|
|
8
|
+
ChainOfThoughtInChat,
|
|
9
|
+
ChainOfThoughtInChatPreview
|
|
10
|
+
)
|
|
11
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ChainOfThoughtCollection(AssetCollection[ChainOfThoughtInChat, ChainOfThoughtInChatPreview]):
|
|
15
|
+
"""Pre-configured collection for Chain of Thought"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, connection: MongoConnection):
|
|
18
|
+
super().__init__(
|
|
19
|
+
collection="chain_of_thoughts",
|
|
20
|
+
asset_type=ChainOfThoughtInChat,
|
|
21
|
+
connection=connection,
|
|
22
|
+
create_instance_method=lambda doc: ChainOfThoughtInChat(**doc),
|
|
23
|
+
preview_type=ChainOfThoughtInChatPreview
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
async def get_by_chat_id(self, chat_id: StrObjectId, skip: int = 0, limit: int = 10) -> List[Dict[str, Any]]:
|
|
27
|
+
"""Get chain of thoughts by chat ID, sorted by created_at (newest first)"""
|
|
28
|
+
cursor = self.async_collection.find({"chat_id": chat_id, "deleted_at": None}).sort("created_at", -1).skip(skip).limit(limit)
|
|
29
|
+
cot_docs = await cursor.to_list(length=None)
|
|
30
|
+
return [self.create_instance(cot_doc).model_dump_json(serializer=SerializerType.FRONTEND) for cot_doc in cot_docs]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Chat Collection - Pre-configured AssetCollection for Chats"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.chat.chat import Chat
|
|
5
|
+
from ....models.base_models import ChattyAssetPreview
|
|
6
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
7
|
+
from ....services.factories.chats.chat_factory import ChatFactory
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ChatCollection(AssetCollection[Chat, ChattyAssetPreview]):
|
|
11
|
+
"""Pre-configured collection for Chat assets"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, connection: MongoConnection):
|
|
14
|
+
super().__init__(
|
|
15
|
+
collection="chats",
|
|
16
|
+
asset_type=Chat,
|
|
17
|
+
connection=connection,
|
|
18
|
+
create_instance_method=ChatFactory.from_json,
|
|
19
|
+
preview_type=None
|
|
20
|
+
)
|
|
21
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Contact Point Collection - Pre-configured AssetCollection for Contact Points"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets.contact_point import ContactPoint
|
|
5
|
+
from ....models.base_models import ChattyAssetPreview
|
|
6
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
7
|
+
from ....services.factories.analytics.contact_point_factory import ContactPointFactory
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ContactPointCollection(AssetCollection[ContactPoint, ChattyAssetPreview]):
|
|
11
|
+
"""Pre-configured collection for ContactPoint assets"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, connection: MongoConnection):
|
|
14
|
+
super().__init__(
|
|
15
|
+
collection="contact_points",
|
|
16
|
+
asset_type=ContactPoint,
|
|
17
|
+
connection=connection,
|
|
18
|
+
create_instance_method=ContactPointFactory.instantiate_contact_point,
|
|
19
|
+
preview_type=None
|
|
20
|
+
)
|
|
21
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""FastAnswer Collection - Pre-configured AssetCollection for Fast Answers"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets import ChattyFastAnswer
|
|
5
|
+
from ....models.base_models import ChattyAssetPreview
|
|
6
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
7
|
+
from ...factories.chatty_fast_answers.chatty_fast_answers_factory import ChattyFastAnswersFactory
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FastAnswerCollection(AssetCollection[ChattyFastAnswer, ChattyAssetPreview]):
|
|
11
|
+
"""Pre-configured collection for Fast Answer assets"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, connection: MongoConnection):
|
|
14
|
+
super().__init__(
|
|
15
|
+
collection="fast_answers",
|
|
16
|
+
asset_type=ChattyFastAnswer,
|
|
17
|
+
connection=connection,
|
|
18
|
+
create_instance_method=ChattyFastAnswersFactory.create,
|
|
19
|
+
preview_type=ChattyAssetPreview
|
|
20
|
+
)
|
|
21
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Filter Criteria Collection - Pre-configured AssetCollection for Filter Criterias"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets.filter_criteria import FilterCriteria, FilterCriteriaPreview
|
|
5
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class FilterCriteriaCollection(AssetCollection[FilterCriteria, FilterCriteriaPreview]):
|
|
9
|
+
"""Pre-configured collection for Filter Criteria assets"""
|
|
10
|
+
|
|
11
|
+
def __init__(self, connection: MongoConnection):
|
|
12
|
+
super().__init__(
|
|
13
|
+
collection="filter_criterias",
|
|
14
|
+
asset_type=FilterCriteria,
|
|
15
|
+
connection=connection,
|
|
16
|
+
create_instance_method=FilterCriteria.default_create_instance_method,
|
|
17
|
+
preview_type=FilterCriteriaPreview
|
|
18
|
+
)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Flow Collection - Pre-configured AssetCollection for Flows"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets.flow import FlowPreview
|
|
5
|
+
from ....models.base_models import ChattyAssetPreview
|
|
6
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FlowCollection(AssetCollection[FlowPreview, ChattyAssetPreview]):
|
|
10
|
+
"""Pre-configured collection for Flow assets"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, connection: MongoConnection):
|
|
13
|
+
super().__init__(
|
|
14
|
+
collection="flows",
|
|
15
|
+
asset_type=FlowPreview,
|
|
16
|
+
connection=connection,
|
|
17
|
+
create_instance_method=FlowPreview.default_create_instance_method,
|
|
18
|
+
preview_type=None
|
|
19
|
+
)
|
|
20
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Product Collection - Pre-configured AssetCollection for Products"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets.product import Product, ProductPreview
|
|
5
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
6
|
+
from ....services.factories.product_factory import ProductFactory
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ProductCollection(AssetCollection[Product, ProductPreview]):
|
|
10
|
+
"""Pre-configured collection for Product assets"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, connection: MongoConnection):
|
|
13
|
+
super().__init__(
|
|
14
|
+
collection="products",
|
|
15
|
+
asset_type=Product,
|
|
16
|
+
connection=connection,
|
|
17
|
+
create_instance_method=ProductFactory.create_product,
|
|
18
|
+
preview_type=ProductPreview
|
|
19
|
+
)
|
|
20
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Sale Collection - Pre-configured AssetCollection for Sales"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets.sale import Sale
|
|
5
|
+
from ....models.base_models import ChattyAssetPreview
|
|
6
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SaleCollection(AssetCollection[Sale, ChattyAssetPreview]):
|
|
10
|
+
"""Pre-configured collection for Sale assets"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, connection: MongoConnection):
|
|
13
|
+
super().__init__(
|
|
14
|
+
collection="sales",
|
|
15
|
+
asset_type=Sale,
|
|
16
|
+
connection=connection,
|
|
17
|
+
create_instance_method=Sale.default_create_instance_method,
|
|
18
|
+
preview_type=None
|
|
19
|
+
)
|
|
20
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Source Collection - Pre-configured AssetCollection for Sources"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.analytics.sources import SourceBase
|
|
5
|
+
from ....models.base_models import ChattyAssetPreview
|
|
6
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
7
|
+
from ....services.factories.analytics.sources.source_factory import SourceFactory
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SourceCollection(AssetCollection[SourceBase, ChattyAssetPreview]):
|
|
11
|
+
"""Pre-configured collection for Source assets"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, connection: MongoConnection):
|
|
14
|
+
super().__init__(
|
|
15
|
+
collection="sources",
|
|
16
|
+
asset_type=SourceBase,
|
|
17
|
+
connection=connection,
|
|
18
|
+
create_instance_method=SourceFactory.instantiate_source,
|
|
19
|
+
preview_type=None
|
|
20
|
+
)
|
|
21
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Tag Collection - Pre-configured AssetCollection for Tags"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets.tag import Tag, TagPreview
|
|
5
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TagCollection(AssetCollection[Tag, TagPreview]):
|
|
9
|
+
"""Pre-configured collection for Tag assets"""
|
|
10
|
+
|
|
11
|
+
def __init__(self, connection: MongoConnection):
|
|
12
|
+
super().__init__(
|
|
13
|
+
collection="tags",
|
|
14
|
+
asset_type=Tag,
|
|
15
|
+
connection=connection,
|
|
16
|
+
create_instance_method=Tag.default_create_instance_method,
|
|
17
|
+
preview_type=TagPreview
|
|
18
|
+
)
|
|
19
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Topic Collection - Pre-configured AssetCollection for Topics"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.analytics.smart_messages.topic import Topic
|
|
5
|
+
from ....models.base_models import ChattyAssetPreview
|
|
6
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
7
|
+
from ...factories.analytics.smart_messages.topics_factory import TopicFactory
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TopicCollection(AssetCollection[Topic, ChattyAssetPreview]):
|
|
11
|
+
"""Pre-configured collection for Topic assets"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, connection: MongoConnection):
|
|
14
|
+
super().__init__(
|
|
15
|
+
collection="topics",
|
|
16
|
+
asset_type=Topic,
|
|
17
|
+
connection=connection,
|
|
18
|
+
create_instance_method=TopicFactory.instantiate_topic,
|
|
19
|
+
preview_type=ChattyAssetPreview
|
|
20
|
+
)
|
|
21
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""User Collection - Pre-configured AssetCollection for Users"""
|
|
2
|
+
|
|
3
|
+
from ..asset_service import AssetCollection
|
|
4
|
+
from ....models.company.assets.users.user import User, UserPreview
|
|
5
|
+
from ....models.data_base.mongo_connection import MongoConnection
|
|
6
|
+
from ....services.users.user_factory import UserFactory
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class UserCollection(AssetCollection[User, UserPreview]):
|
|
10
|
+
"""Pre-configured collection for User assets"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, connection: MongoConnection):
|
|
13
|
+
super().__init__(
|
|
14
|
+
collection="users",
|
|
15
|
+
asset_type=User,
|
|
16
|
+
connection=connection,
|
|
17
|
+
create_instance_method=UserFactory.instantiate_user,
|
|
18
|
+
preview_type=UserPreview
|
|
19
|
+
)
|
|
20
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Example usage of the AssetsCollections class
|
|
3
|
+
|
|
4
|
+
This file demonstrates how to use the read-only AssetsCollections container
|
|
5
|
+
in a microservice.
|
|
6
|
+
"""
|
|
7
|
+
from .assets_collections import AssetsCollections
|
|
8
|
+
from ...models.data_base.mongo_connection import MongoConnection
|
|
9
|
+
|
|
10
|
+
# Example: How to use AssetsCollections in a microservice
|
|
11
|
+
|
|
12
|
+
def example_usage():
|
|
13
|
+
"""
|
|
14
|
+
Example of how to use AssetsCollections in your microservice.
|
|
15
|
+
"""
|
|
16
|
+
# Initialize the connection (typically this would be a singleton in your microservice)
|
|
17
|
+
connection = MongoConnection()
|
|
18
|
+
|
|
19
|
+
# Get the singleton instance
|
|
20
|
+
assets = AssetsCollections(connection)
|
|
21
|
+
|
|
22
|
+
# Read assets by ID
|
|
23
|
+
# product = assets.get_product_by_id("some_product_id")
|
|
24
|
+
# tag = assets.get_tag_by_id("some_tag_id")
|
|
25
|
+
# user = assets.get_user_by_id("some_user_id")
|
|
26
|
+
# chat = assets.get_chat_by_id("some_chat_id")
|
|
27
|
+
# source = assets.get_source_by_id("some_source_id")
|
|
28
|
+
# flow = assets.get_flow_by_id("some_flow_id")
|
|
29
|
+
# sale = assets.get_sale_by_id("some_sale_id")
|
|
30
|
+
# contact_point = assets.get_contact_point_by_id("some_contact_point_id")
|
|
31
|
+
# ai_agent = assets.get_ai_agent_by_id("some_ai_agent_id")
|
|
32
|
+
|
|
33
|
+
# Or access the collections directly for more advanced queries
|
|
34
|
+
# all_products = assets.products.get_docs(query={"active": True}, company_id="some_company_id")
|
|
35
|
+
|
|
36
|
+
print("AssetsCollections initialized and ready to use!")
|
|
37
|
+
|
|
38
|
+
# Note: This is read-only. No insert, update, or delete operations are available.
|
|
39
|
+
# For write operations, use the full AssetService classes in the API.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
example_usage()
|
|
44
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pre-configured Asset Services
|
|
3
|
+
|
|
4
|
+
This module provides ready-to-use AssetService subclasses for each asset type.
|
|
5
|
+
These services include the collection configuration and default cache settings.
|
|
6
|
+
|
|
7
|
+
API implementations can extend these to add business logic (events, validation, etc.)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from .product_service import ProductService
|
|
11
|
+
from .tag_service import TagService
|
|
12
|
+
from .user_service import UserService
|
|
13
|
+
from .chat_service import ChatService
|
|
14
|
+
from .source_service import SourceService
|
|
15
|
+
from .flow_service import FlowService
|
|
16
|
+
from .sale_service import SaleService
|
|
17
|
+
from .contact_point_service import ContactPointService
|
|
18
|
+
from .ai_agent_service import AiAgentService
|
|
19
|
+
from .fast_answer_service import FastAnswerService
|
|
20
|
+
from .topic_service import TopicService
|
|
21
|
+
from .filter_criteria_service import FilterCriteriaService
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
'ProductService',
|
|
25
|
+
'TagService',
|
|
26
|
+
'UserService',
|
|
27
|
+
'ChatService',
|
|
28
|
+
'SourceService',
|
|
29
|
+
'FlowService',
|
|
30
|
+
'SaleService',
|
|
31
|
+
'ContactPointService',
|
|
32
|
+
'AiAgentService',
|
|
33
|
+
'FastAnswerService',
|
|
34
|
+
'TopicService',
|
|
35
|
+
'FilterCriteriaService',
|
|
36
|
+
]
|
|
37
|
+
|