letschatty 0.4.339__tar.gz → 0.4.341__tar.gz

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 (282) hide show
  1. {letschatty-0.4.339 → letschatty-0.4.341}/PKG-INFO +1 -1
  2. {letschatty-0.4.339 → letschatty-0.4.341}/pyproject.toml +1 -1
  3. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/chat.py +11 -2
  4. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/chain_of_thought_in_chat.py +5 -3
  5. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/chat_assets.py +3 -2
  6. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/sale.py +3 -3
  7. letschatty-0.4.341/src/letschatty/models/company/integrations/shopify/shopify_product_sync_status.py +42 -0
  8. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chat/chat_service.py +39 -10
  9. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/validators/analytics_validator.py +11 -0
  10. {letschatty-0.4.339 → letschatty-0.4.341}/LICENSE +0 -0
  11. {letschatty-0.4.339 → letschatty-0.4.341}/README.md +0 -0
  12. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/__init__.py +0 -0
  13. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/__init__.py +0 -0
  14. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/ai_microservices/__init__.py +0 -0
  15. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/ai_microservices/expected_output.py +0 -0
  16. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/ai_microservices/lambda_events.py +0 -0
  17. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/ai_microservices/lambda_invokation_types.py +0 -0
  18. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/ai_microservices/n8n_ai_agents_payload.py +0 -0
  19. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/ai_microservices/openai_payloads.py +0 -0
  20. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/__init__.py +0 -0
  21. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/__init__.py +0 -0
  22. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/base.py +0 -0
  23. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/ai_agent_chat.py +0 -0
  24. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/business_area.py +0 -0
  25. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/chat_based_event.py +0 -0
  26. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/chat_context.py +0 -0
  27. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/chat_funnel.py +0 -0
  28. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/chat_status.py +0 -0
  29. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/contact_point.py +0 -0
  30. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/continuous_conversation.py +0 -0
  31. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/highlight.py +0 -0
  32. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/message.py +0 -0
  33. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/messages_intent_context.py +0 -0
  34. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/product_chat.py +0 -0
  35. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/quality_scoring.py +0 -0
  36. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/sale.py +0 -0
  37. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/tag_chat.py +0 -0
  38. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/chat_based_events/workflow.py +0 -0
  39. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/company_based_events/asset_events.py +0 -0
  40. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/company_based_events/company_events.py +0 -0
  41. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/company_based_events/user_events.py +0 -0
  42. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/event_type_to_classes.py +0 -0
  43. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/events/event_types.py +0 -0
  44. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/metrics/__init_.py +0 -0
  45. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/metrics/daily_contact_points.py +0 -0
  46. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/metrics/daily_new_chats.py +0 -0
  47. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/metrics/daily_sent_templates_grouped.py +0 -0
  48. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/metrics/sales_roadmap.py +0 -0
  49. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/metrics/sent_templates.py +0 -0
  50. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/smart_messages/friendly_code_for_source.py +0 -0
  51. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/smart_messages/topic.py +0 -0
  52. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/smart_messages/topic_message.py +0 -0
  53. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/__init__.py +0 -0
  54. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/google_ad_utm_source.py +0 -0
  55. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/helpers.py +0 -0
  56. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/other_source.py +0 -0
  57. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/pure_ad.py +0 -0
  58. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/pure_ad_utm_source.py +0 -0
  59. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/source_base.py +0 -0
  60. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/template_source.py +0 -0
  61. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/topic_default_source.py +0 -0
  62. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/utm_source.py +0 -0
  63. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/utms/referer_info.py +0 -0
  64. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/utms/utm_query_params.py +0 -0
  65. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/analytics/sources/whatsapp_default_source.py +0 -0
  66. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/auth/jwt.py +0 -0
  67. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/base_models/__init__.py +0 -0
  68. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/base_models/ai_agent_component.py +0 -0
  69. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/base_models/chatty_asset_model.py +0 -0
  70. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/base_models/helpers.py +0 -0
  71. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/base_models/related_asset_usage_example.py +0 -0
  72. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/base_models/singleton.py +0 -0
  73. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/base_models/update_model_interface.py +0 -0
  74. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/base_models/validate_timestamps_and_id.py +0 -0
  75. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/channels/channel.py +0 -0
  76. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/assets_assigned_to_chat.py +0 -0
  77. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/chat_status_modifications.py +0 -0
  78. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/chat_with_assets.py +0 -0
  79. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/client.py +0 -0
  80. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/continuous_conversation.py +0 -0
  81. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/filter_parameters.py +0 -0
  82. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/flow_link_state.py +0 -0
  83. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/highlight.py +0 -0
  84. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/preview.py +0 -0
  85. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/quality_scoring.py +0 -0
  86. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/scheduled_messages.py +0 -0
  87. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/temporary_chat.py +0 -0
  88. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/chat/time_left.py +0 -0
  89. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/CRM/business_area.py +0 -0
  90. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/CRM/funnel.py +0 -0
  91. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/__init__.py +0 -0
  92. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/__init__.py +0 -0
  93. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/ai_agent_message_draft.py +0 -0
  94. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/ai_agents_decision_output.py +0 -0
  95. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/chat_example.py +0 -0
  96. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/chat_example_test.py +0 -0
  97. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/chatty_ai_agent.py +0 -0
  98. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/chatty_ai_agent_config_for_automation.py +0 -0
  99. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/chatty_ai_agent_in_chat.py +0 -0
  100. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/chatty_ai_mode.py +0 -0
  101. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/context_item.py +0 -0
  102. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/faq.py +0 -0
  103. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/follow_up_strategy.py +0 -0
  104. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/get_chat_with_prompt_response.py +0 -0
  105. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/knowleadge_base_components.py +0 -0
  106. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/n8n_agents_info.py +0 -0
  107. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/n8n_schema_incoming_message_output.json +0 -0
  108. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/n8n_schema_smart_follow_up_output.json +0 -0
  109. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/pre_qualify_config.py +0 -0
  110. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/ai_agents_v2/statuses.py +0 -0
  111. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/assignment/__init__.py +0 -0
  112. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/assignment/assignment_assets.py +0 -0
  113. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/automation.py +0 -0
  114. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/chatty_fast_answers/__init__.py +0 -0
  115. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/chatty_fast_answers/chatty_fast_answer.py +0 -0
  116. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/company_assets.py +0 -0
  117. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/contact_point.py +0 -0
  118. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/filter_criteria.py +0 -0
  119. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/flow.py +0 -0
  120. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/launch/__init__.py +0 -0
  121. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/launch/launch.py +0 -0
  122. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/launch/scheduled_communication.py +0 -0
  123. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/launch/subscription.py +0 -0
  124. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/media/__init__.py +0 -0
  125. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/media/file.py +0 -0
  126. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/product.py +0 -0
  127. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/tag.py +0 -0
  128. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/users/agent_chats_snapshot.py +0 -0
  129. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/users/user.py +0 -0
  130. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/users/user_asset_permission.py +0 -0
  131. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/assets/workflow_execution.py +0 -0
  132. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/company_chats_snapshot.py +0 -0
  133. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/company_messaging_settgins.py +0 -0
  134. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/conversation_topic.py +0 -0
  135. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/empresa.py +0 -0
  136. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/form_field.py +0 -0
  137. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/insight.py +0 -0
  138. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/company/notifications/notification.py +0 -0
  139. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/copilot/links.py +0 -0
  140. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/data_base/__init__.py +0 -0
  141. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/data_base/collection_interface.py +0 -0
  142. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/data_base/mongo_connection.py +0 -0
  143. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/execution/__init__.py +0 -0
  144. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/execution/execution.py +0 -0
  145. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/execution/executor.py +0 -0
  146. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/forms/company/auth0_company_registration_form.py +0 -0
  147. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/forms/company/meta_register.py +0 -0
  148. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/__init__.py +0 -0
  149. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/__init__.py +0 -0
  150. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/audio.py +0 -0
  151. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/base/__init__.py +0 -0
  152. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/base/chatty_message_json.py +0 -0
  153. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/base/message_base.py +0 -0
  154. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/base/message_draft.py +0 -0
  155. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/button.py +0 -0
  156. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/central_notification.py +0 -0
  157. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/contact.py +0 -0
  158. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/document.py +0 -0
  159. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/image.py +0 -0
  160. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/interactive.py +0 -0
  161. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/location.py +0 -0
  162. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/reaction.py +0 -0
  163. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/__init__.py +0 -0
  164. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_audio.py +0 -0
  165. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_button.py +0 -0
  166. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_central.py +0 -0
  167. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_contacts.py +0 -0
  168. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_document.py +0 -0
  169. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_image.py +0 -0
  170. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_interactive.py +0 -0
  171. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_location.py +0 -0
  172. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_media.py +0 -0
  173. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_reaction.py +0 -0
  174. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_sticker.py +0 -0
  175. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_text.py +0 -0
  176. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_content/content_video.py +0 -0
  177. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_context/__init__.py +0 -0
  178. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_context/chatty_context.py +0 -0
  179. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_referal/__init__.py +0 -0
  180. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/schema/chatty_referal/chatty_referal.py +0 -0
  181. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/sticker.py +0 -0
  182. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/text.py +0 -0
  183. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/chatty_messages/video.py +0 -0
  184. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/message_templates/__init__.py +0 -0
  185. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/message_templates/chatty_template_campaign.py +0 -0
  186. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/message_templates/filled_data_from_frontend.py +0 -0
  187. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/message_templates/payload_for_sending_template.py +0 -0
  188. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/message_templates/raw_meta_template.py +0 -0
  189. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/message_templates/recipient_of_template_campaign.py +0 -0
  190. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/message_templates/required_for_frontend_templates.py +0 -0
  191. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/meta_base_notification_json.py +0 -0
  192. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/meta_error_json.py +0 -0
  193. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/meta_inexistent_json.py +0 -0
  194. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/meta_message_json.py +0 -0
  195. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/meta_status_json.py +0 -0
  196. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/meta_unknown_json.py +0 -0
  197. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/__init__.py +0 -0
  198. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/button_content.py +0 -0
  199. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/contacts_content.py +0 -0
  200. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/interactive_content.py +0 -0
  201. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/location_content.py +0 -0
  202. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/multimedia_content.py +0 -0
  203. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/order_content.py +0 -0
  204. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/reaction_content.py +0 -0
  205. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/system_content.py +0 -0
  206. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/content_messages/text_content.py +0 -0
  207. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/values/__init__.py +0 -0
  208. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/values/value_errors.py +0 -0
  209. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/values/value_messages.py +0 -0
  210. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/messages/meta_message_model/schema/values/value_statuses.py +0 -0
  211. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/__init__.py +0 -0
  212. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/custom_exceptions/__init__.py +0 -0
  213. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/custom_exceptions/custom_exceptions.py +0 -0
  214. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/definitions.py +0 -0
  215. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/CRUD_operations.py +0 -0
  216. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/__init__.py +0 -0
  217. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/channel_types.py +0 -0
  218. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/chats_actions.py +0 -0
  219. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/country.py +0 -0
  220. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/deletion_type.py +0 -0
  221. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/executor_types.py +0 -0
  222. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/identifier.py +0 -0
  223. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/message_status_types.py +0 -0
  224. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/message_types.py +0 -0
  225. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/phone_number.py +0 -0
  226. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/serializer_type.py +0 -0
  227. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/source_types.py +0 -0
  228. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/models/utils/types/typealiases.py +0 -0
  229. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/__init__.py +0 -0
  230. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/ai_agents/context_builder_v2.py +0 -0
  231. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/ai_agents/cot_follow_up_examples.py +0 -0
  232. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/ai_agents/followup_schema.json +0 -0
  233. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/ai_agents/smart_follow_up_context_builder_v2.py +0 -0
  234. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/ai_agents/smart_follow_up_service_v2.py +0 -0
  235. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/ai_agents/tool_descriptions/assign_chat_to_ai_agent_itself.json +0 -0
  236. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/ai_agents/tool_descriptions/human_handover.json +0 -0
  237. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/ai_agents/tool_descriptions.py +0 -0
  238. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/ai_components_service.py +0 -0
  239. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chat/chat_extractors.py +0 -0
  240. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chat/client_service.py +0 -0
  241. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chat/conversation_topics_service.py +0 -0
  242. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chatty_assets/__init__.py +0 -0
  243. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chatty_assets/asset_service.py +0 -0
  244. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chatty_assets/base_container.py +0 -0
  245. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chatty_assets/base_container_with_collection.py +0 -0
  246. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chatty_assets/documentation_diagram.png +0 -0
  247. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/chatty_assets/readme.md +0 -0
  248. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/concurrent/concurrent.py +0 -0
  249. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/contact_points/contact_point_service.py +0 -0
  250. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/continuous_conversation_service/continuous_conversation_helper.py +0 -0
  251. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/events/events_manager.py +0 -0
  252. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/__init__.py +0 -0
  253. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/analytics/contact_point_factory.py +0 -0
  254. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/analytics/events_factory.py +0 -0
  255. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/analytics/smart_messages/topics_factory.py +0 -0
  256. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/analytics/sources/helpers.py +0 -0
  257. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/analytics/sources/source_factory.py +0 -0
  258. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/chats/chat_factory.py +0 -0
  259. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/chatty_fast_answers/__init__.py +0 -0
  260. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/chatty_fast_answers/chatty_fast_answers_factory.py +0 -0
  261. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/clients/client_factory.py +0 -0
  262. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/company/__init__.py +0 -0
  263. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/company/empresa_factory.py +0 -0
  264. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/lambda_ai_orchestrartor/lambda_events_factory.py +0 -0
  265. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/messages/__init__.py +0 -0
  266. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/messages/central_notification_factory.py +0 -0
  267. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/messages/chatty_message_factory.py +0 -0
  268. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/messages/child_db_message_factory.py +0 -0
  269. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/messages/child_request_message.py +0 -0
  270. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/messages/from_template_hot_fix.py +0 -0
  271. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/messages/message_templates/template_factory.py +0 -0
  272. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/messages/message_templates/test.py +0 -0
  273. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/meta_notifications/__init__.py +0 -0
  274. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/meta_notifications/meta_notification_factory.py +0 -0
  275. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/factories/product_factory.py +0 -0
  276. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/filter_criteria_service.py +0 -0
  277. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/messages_helpers/__init__.py +0 -0
  278. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/messages_helpers/get_caption_or_body_or_preview.py +0 -0
  279. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/scheduled_messages_service/scheduled_messages_helpers.py +0 -0
  280. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/template_campaigns/template_campaign_service.py +0 -0
  281. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/users/agent_service.py +0 -0
  282. {letschatty-0.4.339 → letschatty-0.4.341}/src/letschatty/services/users/user_factory.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: letschatty
3
- Version: 0.4.339
3
+ Version: 0.4.341
4
4
  Summary: Models and custom classes to work across the Chattyverse
5
5
  License: MIT
6
6
  Author: Axel
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "letschatty"
3
- version = "0.4.339" # Or whichever is your latest version
3
+ version = "0.4.341" # Or whichever is your latest version
4
4
  description = "Models and custom classes to work across the Chattyverse"
5
5
  authors = ["Axel <axel@letschatty.com>"]
6
6
  license = "MIT"
@@ -269,7 +269,17 @@ class Chat(CompanyAssetModel):
269
269
  @property
270
270
  def bought_product_ids(self) -> List[StrObjectId]:
271
271
  """Get all sale ids in the chat"""
272
- return [sale.product_id for sale in self.sales]
272
+ product_ids: List[StrObjectId] = []
273
+ for sale in self.sales:
274
+ sale_product_ids = getattr(sale, "product_ids", None)
275
+ if sale_product_ids:
276
+ for product_id in sale_product_ids:
277
+ if product_id not in product_ids:
278
+ product_ids.append(product_id)
279
+ elif sale.product_id:
280
+ if sale.product_id not in product_ids:
281
+ product_ids.append(sale.product_id)
282
+ return product_ids
273
283
 
274
284
  @property
275
285
  def products(self) -> List[AssignedAssetToChat]:
@@ -366,4 +376,3 @@ class Chat(CompanyAssetModel):
366
376
  dump["last_message"] = self.last_message.model_dump_json(serializer=SerializerType.DATABASE) if self.last_message else None
367
377
  dump["flow_states"] = [flow_state.model_dump_json(serializer=SerializerType.DATABASE) for flow_state in self.flow_states]
368
378
  return dump
369
-
@@ -84,12 +84,13 @@ class ChainOfThoughtInChatPreview(ChattyAssetPreview):
84
84
  # trigger_id removed - trigger info is in: incoming_message_ids for user_message,
85
85
  # triggered_by_user_id for manual_trigger, smart_follow_up_id for follow_up
86
86
  chain_of_thought : Optional[str] = Field(default=None, description="The chain of thought")
87
+ confidence: Optional[int] = Field(default=None, ge=0, le=100, description="Confidence 0-100")
87
88
  status: Optional[ChainOfThoughtInChatStatus] = Field(default=None, description="The status of the chain of thought")
88
89
  name: str = Field(description="A title for the chain of thought")
89
90
 
90
91
  @classmethod
91
92
  def get_projection(cls) -> dict[str, Any]:
92
- return super().get_projection() | {"chat_id": 1, "trigger": 1, "chain_of_thought": 1, "name": 1, "status": 1}
93
+ return super().get_projection() | {"chat_id": 1, "trigger": 1, "chain_of_thought": 1, "confidence": 1, "name": 1, "status": 1}
93
94
 
94
95
  @classmethod
95
96
  def from_dict(cls, data: dict) -> 'ChainOfThoughtInChatPreview':
@@ -103,6 +104,7 @@ class ChainOfThoughtInChatPreview(ChattyAssetPreview):
103
104
  chat_id=asset.chat_id,
104
105
  trigger=asset.trigger,
105
106
  chain_of_thought=asset.chain_of_thought,
107
+ confidence=asset.confidence,
106
108
  status=asset.status,
107
109
  company_id=asset.company_id,
108
110
  created_at=asset.created_at,
@@ -121,6 +123,7 @@ class ChainOfThoughtInChat(CompanyAssetModel):
121
123
  chatty_ai_agent_id : StrObjectId = Field(description="The chatty ai agent id")
122
124
  chatty_ai_agent : Dict[str, Any] = Field(description="The chatty ai agent at the moment of triggering the chain of thought", exclude=True,default_factory=dict)
123
125
  chain_of_thought : Optional[str] = Field(default=None, description="The chain of thought")
126
+ confidence: Optional[int] = Field(default=None, ge=0, le=100, description="Confidence 0-100")
124
127
  name: str = Field(description="A title for the chain of thought", alias="title")
125
128
  preview_class: ClassVar[Type[ChattyAssetPreview]] = ChainOfThoughtInChatPreview
126
129
 
@@ -128,5 +131,4 @@ class ChainOfThoughtInChat(CompanyAssetModel):
128
131
  if self.chain_of_thought is None:
129
132
  self.chain_of_thought = cot
130
133
  else:
131
- self.chain_of_thought += f"\n{cot}"
132
-
134
+ self.chain_of_thought += f"\n{cot}"
@@ -10,7 +10,7 @@ from datetime import datetime
10
10
  from zoneinfo import ZoneInfo
11
11
  from bson import ObjectId
12
12
  import json
13
- from typing import Dict, Any, Optional
13
+ from typing import Dict, Any, Optional, List
14
14
  from letschatty.models.utils.types.serializer_type import SerializerType
15
15
  from letschatty.models.company.assets.ai_agents_v2.chatty_ai_mode import ChattyAIMode
16
16
 
@@ -67,7 +67,8 @@ class AssignedAssetToChat(BaseModel):
67
67
 
68
68
 
69
69
  class SaleAssignedToChat(AssignedAssetToChat):
70
- product_id: StrObjectId = Field(frozen=True)
70
+ product_id: Optional[StrObjectId] = Field(default=None)
71
+ product_ids: List[StrObjectId] = Field(default_factory=list)
71
72
 
72
73
  class ContactPointAssignedToChat(AssignedAssetToChat):
73
74
  source_id: StrObjectId = Field(frozen=True)
@@ -5,7 +5,7 @@ from ...utils.types.identifier import StrObjectId
5
5
 
6
6
  class Sale(CompanyAssetModel):
7
7
  chat_id: StrObjectId
8
- product_id: StrObjectId
8
+ product_id: Optional[StrObjectId] = Field(default=None)
9
9
  quantity: int
10
10
  total_amount: float
11
11
  currency: str
@@ -16,7 +16,7 @@ class Sale(CompanyAssetModel):
16
16
  creator_id: StrObjectId
17
17
 
18
18
  class SaleRequest(BaseModel):
19
- product_id: StrObjectId
19
+ product_id: Optional[StrObjectId] = Field(default=None)
20
20
  quantity: int
21
21
  creator_id: StrObjectId
22
22
  total_amount: float
@@ -36,4 +36,4 @@ class SaleRequest(BaseModel):
36
36
  "paid_amount": 100,
37
37
  "installments": 1,
38
38
  "details": {}
39
- }
39
+ }
@@ -0,0 +1,42 @@
1
+ from enum import Enum
2
+ from typing import Optional
3
+ from datetime import datetime
4
+ from zoneinfo import ZoneInfo
5
+ from pydantic import Field
6
+ from letschatty.models.base_models import CompanyAssetModel
7
+
8
+
9
+ class ShopifyProductSyncStatusEnum(str, Enum):
10
+ """Status enum for Shopify product sync operations"""
11
+ STARTED = "started"
12
+ RUNNING = "running"
13
+ FINISHED = "finished"
14
+ FAILED = "failed"
15
+
16
+
17
+ class ShopifyProductSyncStatus(CompanyAssetModel):
18
+ """Tracks the status and results of Shopify product synchronization operations.
19
+
20
+ Each sync operation creates a new document in the collection with its own status,
21
+ timestamps, and product counts.
22
+ """
23
+ name: str = Field(
24
+ default="",
25
+ description="Name/identifier for this sync operation"
26
+ )
27
+ status: ShopifyProductSyncStatusEnum = Field(
28
+ default=ShopifyProductSyncStatusEnum.STARTED,
29
+ description="Current sync status"
30
+ )
31
+ finished_at: Optional[datetime] = Field(
32
+ default=None,
33
+ description="Timestamp when sync finished"
34
+ )
35
+ products_created: int = Field(
36
+ default=0,
37
+ description="Number of products created during sync"
38
+ )
39
+ products_updated: int = Field(
40
+ default=0,
41
+ description="Number of products updated during sync"
42
+ )
@@ -211,6 +211,25 @@ class ChatService:
211
211
  ChatService.add_central_notification_from_text(chat=chat, body=f"Agente de IA {chatty_ai_agent.name} actualizado en el chat {chat.id} por {execution_context.executor.name}", subtype=MessageSubtype.CHATTY_AI_AGENT_UPDATED)
212
212
  return chat.chatty_ai_agent
213
213
 
214
+ @staticmethod
215
+ def escalate_chatty_ai_agent(chat: Chat, execution_context: ExecutionContext, message: Optional[str] = None) -> None:
216
+ """
217
+ Mark the chat's AI agent as requiring human intervention and add a central notification.
218
+ """
219
+ if chat.chatty_ai_agent and not chat.chatty_ai_agent.requires_human_intervention:
220
+ chat.chatty_ai_agent.requires_human_intervention = True
221
+ execution_context.set_event_time(datetime.now(tz=ZoneInfo("UTC")))
222
+ body = "El chat fue escalado a un agente humano"
223
+ if message:
224
+ body = f"{body}: {message}"
225
+ ChatService.add_central_notification_from_text(
226
+ chat=chat,
227
+ body=body,
228
+ subtype=MessageSubtype.CHATTY_AI_AGENT_NOTIFICATION,
229
+ content_status=CentralNotificationStatus.WARNING,
230
+ context=ChattyContext(chain_of_thought_id=execution_context.chain_of_thought_id)
231
+ )
232
+
214
233
  @staticmethod
215
234
  def add_workflow_link(chat : Chat, link : LinkItem, flow:FlowPreview, execution_context: ExecutionContext, description: str, last_incoming_message_id: Optional[str] = None, next_call: Optional[datetime] = None) -> FlowStateAssignedToChat:
216
235
  """
@@ -266,36 +285,46 @@ class ChatService:
266
285
  return next((state for state in chat.flow_states if state.is_smart_follow_up), None)
267
286
 
268
287
  @staticmethod
269
- def create_sale(chat : Chat, execution_context: ExecutionContext, sale : Sale, product : Product) -> SaleAssignedToChat:
288
+ def create_sale(
289
+ chat: Chat,
290
+ execution_context: ExecutionContext,
291
+ sale: Sale,
292
+ product: Optional[Product],
293
+ product_ids: Optional[List[StrObjectId]] = None,
294
+ product_label: Optional[str] = None
295
+ ) -> SaleAssignedToChat:
270
296
  """
271
297
  Add a sale to the chat.
272
298
  """
273
299
  if next((sale for sale in chat.client.sales if sale.asset_id == sale.id), None) is not None:
274
300
  raise AssetAlreadyAssigned(f"Sale with id {sale.id} already assigned to chat {chat.id}")
301
+ label = product_label or (product.name if product else "multiples productos")
302
+ assigned_product_ids = product_ids or ([product.id] if product else [])
275
303
  assigned_asset = SaleAssignedToChat(
276
304
  asset_type=ChatAssetType.SALE,
277
305
  asset_id=sale.id,
278
306
  assigned_at=sale.created_at,
279
307
  assigned_by=execution_context.executor.id,
280
- product_id=product.id
308
+ product_id=product.id if product else None,
309
+ product_ids=assigned_product_ids
281
310
  )
282
311
  execution_context.set_event_time(assigned_asset.assigned_at)
283
312
  bisect.insort(chat.client.sales, assigned_asset)
284
- ChatService.create_highlight(chat=chat, execution_context=execution_context, highlight_data=HighlightRequestData(title=f"🛍️ Venta de {product.name}", description=f"Venta de {product.name} creada por {execution_context.executor.name}", starred=False, subtype=MessageSubtype.SALE_ADDED))
285
- ChatService.add_central_notification_from_text(chat=chat, body=f"Venta de {product.name} agregada al chat {chat.id} por {execution_context.executor.name}", subtype=MessageSubtype.SALE_ADDED)
313
+ ChatService.create_highlight(chat=chat, execution_context=execution_context, highlight_data=HighlightRequestData(title=f"🛍️ Venta de {label}", description=f"Venta de {label} creada por {execution_context.executor.name}", starred=False, subtype=MessageSubtype.SALE_ADDED))
314
+ ChatService.add_central_notification_from_text(chat=chat, body=f"Venta de {label} agregada al chat {chat.id} por {execution_context.executor.name}", subtype=MessageSubtype.SALE_ADDED)
286
315
  return assigned_asset
287
316
 
288
317
  @staticmethod
289
- def update_sale(chat : Chat, execution_context: ExecutionContext, sale : Sale, product : Product) -> Sale:
318
+ def update_sale(chat: Chat, execution_context: ExecutionContext, sale: Sale, product_label: str) -> Sale:
290
319
  """
291
320
  Update a sale for the chat.
292
321
  """
293
- ChatService.create_highlight(chat=chat, execution_context=execution_context, highlight_data=HighlightRequestData(title=f"🛍️ Venta actualizada de {product.name}", description=f"Venta de {product.name} actualizada por {execution_context.executor.name}", starred=False, subtype=MessageSubtype.SALE_UPDATED))
294
- ChatService.add_central_notification_from_text(chat=chat, body=f"Venta de {product.name} actualizada en el chat {chat.id} por {execution_context.executor.name}", subtype=MessageSubtype.SALE_UPDATED)
322
+ ChatService.create_highlight(chat=chat, execution_context=execution_context, highlight_data=HighlightRequestData(title=f"🛍️ Venta actualizada de {product_label}", description=f"Venta de {product_label} actualizada por {execution_context.executor.name}", starred=False, subtype=MessageSubtype.SALE_UPDATED))
323
+ ChatService.add_central_notification_from_text(chat=chat, body=f"Venta de {product_label} actualizada en el chat {chat.id} por {execution_context.executor.name}", subtype=MessageSubtype.SALE_UPDATED)
295
324
  return sale
296
325
 
297
326
  @staticmethod
298
- def delete_sale(chat : Chat, execution_context: ExecutionContext, sale_id : StrObjectId, product : Product) -> SaleAssignedToChat:
327
+ def delete_sale(chat: Chat, execution_context: ExecutionContext, sale_id: StrObjectId, product_label: str) -> SaleAssignedToChat:
299
328
  """
300
329
  Logically remove a sale from the chat.
301
330
  """
@@ -303,8 +332,8 @@ class ChatService:
303
332
  assigned_asset_to_remove = next(sale for sale in chat.client.sales if sale.asset_id == sale_id)
304
333
  chat.client.sales.remove(assigned_asset_to_remove)
305
334
  execution_context.set_event_time(datetime.now(tz=ZoneInfo("UTC")))
306
- ChatService.create_highlight(chat=chat, execution_context=execution_context, highlight_data=HighlightRequestData(title=f"🛍️ Venta eliminada de {product.name}", description=f"Venta de {product.name} eliminada por {execution_context.executor.name}", starred=False, subtype=MessageSubtype.SALE_DELETED))
307
- ChatService.add_central_notification_from_text(chat=chat, body=f"Venta de {product.name} eliminada del chat {chat.id} por {execution_context.executor.name}", subtype=MessageSubtype.SALE_DELETED)
335
+ ChatService.create_highlight(chat=chat, execution_context=execution_context, highlight_data=HighlightRequestData(title=f"🛍️ Venta eliminada de {product_label}", description=f"Venta de {product_label} eliminada por {execution_context.executor.name}", starred=False, subtype=MessageSubtype.SALE_DELETED))
336
+ ChatService.add_central_notification_from_text(chat=chat, body=f"Venta de {product_label} eliminada del chat {chat.id} por {execution_context.executor.name}", subtype=MessageSubtype.SALE_DELETED)
308
337
  return assigned_asset_to_remove
309
338
  except StopIteration:
310
339
  raise NotFoundError(message=f"Sale with id {sale_id} not found in chat {chat.id}")
@@ -10,6 +10,10 @@ if TYPE_CHECKING:
10
10
 
11
11
  class SourcesAndTopicsValidator:
12
12
  """This class provides methods to validate sources and topics."""
13
+ @staticmethod
14
+ def normalize_source_name(name: str) -> str:
15
+ return name.strip().lower()
16
+
13
17
  @staticmethod
14
18
  def source_validation_check(sources : Dict[str,Source], topics : Dict[str,Topic], source : Source, existing_source_id : str | None = None) -> None:
15
19
  """Checks validation of a source against other sources and topics."""
@@ -28,9 +32,16 @@ class SourcesAndTopicsValidator:
28
32
  """This method checks that no duplicated source is created.
29
33
  For Pure Ads, it checks that the ad_id is unique and doesn't exist already.
30
34
  For Other Sources, it checks that exact trigger doesn't exist already. """
35
+ normalized_name = SourcesAndTopicsValidator.normalize_source_name(source.name)
36
+ existing_source_name = None
37
+ if existing_source_id and existing_source_id in sources:
38
+ existing_source_name = SourcesAndTopicsValidator.normalize_source_name(sources[existing_source_id].name)
39
+ should_check_name = existing_source_name is None or normalized_name != existing_source_name
31
40
  for source_id, source_to_check in sources.items():
32
41
  if source_id == existing_source_id:
33
42
  continue
43
+ if should_check_name and SourcesAndTopicsValidator.normalize_source_name(source_to_check.name) == normalized_name:
44
+ raise ConflictedSource(f":warning: *Conflict while adding source: Name already exists* \n New source '{source.name}' \n- Id {source.id} \n Existing source '{source_to_check.name}' \n- Id {source_to_check.id}", conflicting_source_id=source_to_check.id)
34
45
  if source == source_to_check: #type: ignore
35
46
  if isinstance(source, OtherSource):
36
47
  raise ConflictedSource(f":warning: *Conflict while adding source: Trigger already exists* \n New source '{source.name}' \n- Id {source.id} \n- Trigger {source.trigger[:30]} \n Existing source '{source_to_check.name}' \n- Id {source_to_check.id} \n- Trigger '{source_to_check.trigger[:30]}'", conflicting_source_id=source_to_check.id)
File without changes
File without changes