bertrend 0.3.16__tar.gz → 0.3.17__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 (220) hide show
  1. {bertrend-0.3.16 → bertrend-0.3.17}/PKG-INFO +1 -1
  2. bertrend-0.3.17/bertrend/llm_utils/prompts.py +138 -0
  3. bertrend-0.3.17/bertrend/topic_analysis/prompts.py +76 -0
  4. bertrend-0.3.17/bertrend/trend_analysis/prompts.py +308 -0
  5. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/i18n_translations.py +4 -0
  6. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/llm_utils.py +1 -1
  7. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/report_generation.py +1 -0
  8. {bertrend-0.3.16 → bertrend-0.3.17}/pyproject.toml +1 -1
  9. bertrend-0.3.16/bertrend/llm_utils/prompts.py +0 -94
  10. bertrend-0.3.16/bertrend/topic_analysis/prompts.py +0 -42
  11. bertrend-0.3.16/bertrend/trend_analysis/prompts.py +0 -306
  12. {bertrend-0.3.16 → bertrend-0.3.17}/AUTHORS.txt +0 -0
  13. {bertrend-0.3.16 → bertrend-0.3.17}/LICENSE.md +0 -0
  14. {bertrend-0.3.16 → bertrend-0.3.17}/README.md +0 -0
  15. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/BERTopicModel.py +0 -0
  16. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/BERTrend.py +0 -0
  17. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/__init__.py +0 -0
  18. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/article_scoring/__init__.py +0 -0
  19. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/article_scoring/article_scoring.py +0 -0
  20. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/article_scoring/prompts.py +0 -0
  21. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/article_scoring/scoring_agent.py +0 -0
  22. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/config/bertopic_default_config.toml +0 -0
  23. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/config/bertrend_default_config.toml +0 -0
  24. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/config/parameters.py +0 -0
  25. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/config/services_default_config.toml +0 -0
  26. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/__init__.py +0 -0
  27. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/demos_utils/__init__.py +0 -0
  28. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/demos_utils/data_loading_component.py +0 -0
  29. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/demos_utils/embed_documents_component.py +0 -0
  30. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/demos_utils/i18n.py +0 -0
  31. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/demos_utils/i18n_translations.py +0 -0
  32. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/demos_utils/icons.py +0 -0
  33. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/demos_utils/parameters_component.py +0 -0
  34. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/demos_utils/state_utils.py +0 -0
  35. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/start_summarizer_app.sh +0 -0
  36. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/start_topic_analysis_app.sh +0 -0
  37. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/start_weak_signals_app.sh +0 -0
  38. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/streamlit_components/__init__.py +0 -0
  39. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/streamlit_components/clickable_df_component.py +0 -0
  40. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/streamlit_components/input_with_pills_components.py +0 -0
  41. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/summarization/__init__.py +0 -0
  42. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/summarization/summarizer_app.py +0 -0
  43. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/.streamlit/config.toml +0 -0
  44. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/__init__.py +0 -0
  45. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/app.py +0 -0
  46. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/app_utils.py +0 -0
  47. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/demo_pages/__init__.py +0 -0
  48. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/demo_pages/explore_topics.py +0 -0
  49. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/demo_pages/newsletters_generation.py +0 -0
  50. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/demo_pages/temporal_visualizations.py +0 -0
  51. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/demo_pages/topic_visualizations.py +0 -0
  52. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/demo_pages/training_page.py +0 -0
  53. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/topic_analysis/i18n_translations.py +0 -0
  54. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/weak_signals/.streamlit/config.toml +0 -0
  55. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/weak_signals/__init__.py +0 -0
  56. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/weak_signals/app.py +0 -0
  57. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/weak_signals/i18n_translations.py +0 -0
  58. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/demos/weak_signals/visualizations_utils.py +0 -0
  59. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/llm_utils/__init__.py +0 -0
  60. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/llm_utils/agent_utils.py +0 -0
  61. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/llm_utils/newsletter.css +0 -0
  62. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/llm_utils/newsletter_features.py +0 -0
  63. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/llm_utils/newsletter_model.py +0 -0
  64. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/llm_utils/newsletter_outlook_template.html +0 -0
  65. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/llm_utils/newsletter_template.html +0 -0
  66. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/llm_utils/openai_client.py +0 -0
  67. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/metrics/__init__.py +0 -0
  68. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/metrics/temporal_metrics_embedding.py +0 -0
  69. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/metrics/topic_metrics.py +0 -0
  70. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/resources/common_ngrams.json +0 -0
  71. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/resources/stopwords-en.json +0 -0
  72. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/resources/stopwords-fr.json +0 -0
  73. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/resources/stopwords-rte.json +0 -0
  74. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/__init__.py +0 -0
  75. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/authentication.py +0 -0
  76. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_client.py +0 -0
  77. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/README.md +0 -0
  78. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/__init__.py +0 -0
  79. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/bertrend_client_registry.json +0 -0
  80. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/config/default_config.toml +0 -0
  81. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/config/settings.py +0 -0
  82. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/main.py +0 -0
  83. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/models.py +0 -0
  84. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/routers/__init__.py +0 -0
  85. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/routers/authentication.py +0 -0
  86. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/routers/embeddings.py +0 -0
  87. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/routers/info.py +0 -0
  88. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/security.py +0 -0
  89. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/start.py +0 -0
  90. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/status.py +0 -0
  91. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_server/stop.py +0 -0
  92. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/embedding_service.py +0 -0
  93. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/summarizer.py +0 -0
  94. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/summary/__init__.py +0 -0
  95. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/summary/abstractive_summarizer.py +0 -0
  96. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/summary/chatgpt_summarizer.py +0 -0
  97. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/summary/extractive_summarizer.py +0 -0
  98. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/summary/lexrank.py +0 -0
  99. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/services/summary/prompts.py +0 -0
  100. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/README_integration_tests.md +0 -0
  101. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/__init__.py +0 -0
  102. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/conftest.py +0 -0
  103. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_abstractive_summarizer.py +0 -0
  104. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_agent_utils.py +0 -0
  105. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_article_scoring.py +0 -0
  106. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_article_scoring_models.py +0 -0
  107. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_bertrend.py +0 -0
  108. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_cache_utils.py +0 -0
  109. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_chatgpt_summarizer.py +0 -0
  110. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_config_utils.py +0 -0
  111. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_data_loading.py +0 -0
  112. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_data_structure.py +0 -0
  113. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_embedding_client.py +0 -0
  114. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_extractive_summarizer.py +0 -0
  115. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_installation.py +0 -0
  116. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_integration.py +0 -0
  117. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_mail_utils.py +0 -0
  118. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_newsletter_features.py +0 -0
  119. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_newsletter_model.py +0 -0
  120. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_openai_client.py +0 -0
  121. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_representative_docs.py +0 -0
  122. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_summarizer.py +0 -0
  123. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_temporal_metrics_embedding.py +0 -0
  124. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_topic_description.py +0 -0
  125. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_topic_metrics.py +0 -0
  126. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_topic_model.py +0 -0
  127. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_trend_analysis_data_structure.py +0 -0
  128. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_trend_analysis_prompts.py +0 -0
  129. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_trend_analysis_visualizations.py +0 -0
  130. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_trend_analysis_weak_signals.py +0 -0
  131. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_utils_init.py +0 -0
  132. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/tests/test_visualizations.py +0 -0
  133. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/topic_analysis/__init__.py +0 -0
  134. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/topic_analysis/data_structure.py +0 -0
  135. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/topic_analysis/representative_docs.py +0 -0
  136. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/topic_analysis/topic_description.py +0 -0
  137. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/topic_analysis/visualizations.py +0 -0
  138. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/trend_analysis/__init__.py +0 -0
  139. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/trend_analysis/data_structure.py +0 -0
  140. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/trend_analysis/signal_llm_template_en.html +0 -0
  141. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/trend_analysis/signal_llm_template_fr.html +0 -0
  142. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/trend_analysis/visualizations.py +0 -0
  143. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/trend_analysis/weak_signals.py +0 -0
  144. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/utils/__init__.py +0 -0
  145. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/utils/cache_utils.py +0 -0
  146. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/utils/config_utils.py +0 -0
  147. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend/utils/data_loading.py +0 -0
  148. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/__init__.py +0 -0
  149. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/common/__init__.py +0 -0
  150. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/common/crontab_utils.py +0 -0
  151. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/common/mail_utils.py +0 -0
  152. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/feeds/arxiv_feed.toml +0 -0
  153. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/feeds/decarbonation_feed.toml +0 -0
  154. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/feeds/llm_en_feed.toml +0 -0
  155. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/feeds/llm_feed.toml +0 -0
  156. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/feeds/nlp_feed.toml +0 -0
  157. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/feeds/rte_feed.toml +0 -0
  158. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/newsletters/arxiv_newsletter_from_last.toml +0 -0
  159. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/newsletters/decarbonation_newsletter_from_last.toml +0 -0
  160. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/newsletters/decarbonation_newsletter_from_scratch.toml +0 -0
  161. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/newsletters/llm_en_newsletter_from_last.toml +0 -0
  162. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/newsletters/llm_newsletter_from_last.toml +0 -0
  163. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/newsletters/nlp_newsletter_from_last.toml +0 -0
  164. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/newsletters/rte_newsletter_from_last.toml +0 -0
  165. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/config/newsletters/rte_newsletter_from_scratch.toml +0 -0
  166. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/data_provider/__init__.py +0 -0
  167. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/data_provider/__main__.py +0 -0
  168. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/data_provider/arxiv_provider.py +0 -0
  169. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/data_provider/atom_feed_provider.py +0 -0
  170. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/data_provider/bing_news_provider.py +0 -0
  171. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/data_provider/data_provider.py +0 -0
  172. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/data_provider/google_news_provider.py +0 -0
  173. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/data_provider/newscatcher_provider.py +0 -0
  174. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/data_provider/utils.py +0 -0
  175. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/__init__.py +0 -0
  176. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/.streamlit/config.toml +0 -0
  177. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/__init__.py +0 -0
  178. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/app.py +0 -0
  179. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/app_utils.py +0 -0
  180. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/config.toml +0 -0
  181. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/import_extraction_article.ipynb +0 -0
  182. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/prompts.py +0 -0
  183. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/start_newsletter_generator.sh +0 -0
  184. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/tabs/tab1.py +0 -0
  185. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/tabs/tab2.py +0 -0
  186. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/curebot/tabs/tab3.py +0 -0
  187. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/dataviz/Main_page.py +0 -0
  188. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/dataviz/__init__.py +0 -0
  189. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/dataviz/pages/1_Data_feeds.py +0 -0
  190. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/geolocalization/__init__.py +0 -0
  191. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/geolocalization/entity_utils.py +0 -0
  192. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/geolocalization/spacy/__init__.py +0 -0
  193. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/geolocalization/spacy/common_factory.py +0 -0
  194. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/geolocalization/spacy/dbpedia.py +0 -0
  195. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/geolocalization/spacy/nlp.config +0 -0
  196. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/exploration/geolocalization/spacy/utils.py +0 -0
  197. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/install_feeds_and_newsletters.py +0 -0
  198. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/newsletters/__init__.py +0 -0
  199. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/newsletters/__main__.py +0 -0
  200. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/.streamlit/config.toml +0 -0
  201. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/.streamlit/secrets.toml +0 -0
  202. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/__init__.py +0 -0
  203. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/app.py +0 -0
  204. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/authentication.py +0 -0
  205. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/dashboard_analysis.py +0 -0
  206. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/dashboard_common.py +0 -0
  207. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/dashboard_signals.py +0 -0
  208. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/data_model.py +0 -0
  209. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/detailed_report_template.html +0 -0
  210. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/feeds_common.py +0 -0
  211. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/feeds_config.py +0 -0
  212. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/feeds_data.py +0 -0
  213. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/models_info.py +0 -0
  214. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/perf_utils.py +0 -0
  215. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/process_new_data.py +0 -0
  216. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/prospective_demo/start_demo.sh +0 -0
  217. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/start_apps.sh +0 -0
  218. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/stop_apps.sh +0 -0
  219. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/tests/__init__.py +0 -0
  220. {bertrend-0.3.16 → bertrend-0.3.17}/bertrend_apps/tests/test_process_new_data.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bertrend
3
- Version: 0.3.16
3
+ Version: 0.3.17
4
4
  Summary: BERTrend analyses topic evolution over time using state-of-the-art transformer models: topic modelling and LLM
5
5
  License: LICENSE.md
6
6
  License-File: AUTHORS.txt
@@ -0,0 +1,138 @@
1
+ # Copyright (c) 2024, RTE (https://www.rte-france.com)
2
+ # See AUTHORS.txt
3
+ # SPDX-License-Identifier: MPL-2.0
4
+ # This file is part of BERTrend.
5
+
6
+ FR_USER_SUMMARY_MULTIPLE_DOCS = """
7
+ Vous êtes une IA spécialisée dans la compréhension et la synthèse d’articles de presse.
8
+ Votre tâche : produire une synthèse concise et fidèle au contenu fourni.
9
+
10
+ Entrées :
11
+ - Mots-clés du thème : {keywords}
12
+ - Articles (Titre + Contenu) :
13
+ ```{article_list}```
14
+
15
+ Exigences de la synthèse :
16
+ 1) Contenu :
17
+ - Être directement liée au thème évoqué par les mots-clés.
18
+ - Intégrer les informations essentielles communes ou complémentaires entre les articles.
19
+ - Éviter les répétitions, les détails anecdotiques et le bruit.
20
+ - Mentionner les acteurs, faits, dates, chiffres et positions clés quand disponibles.
21
+ - Être neutre, factuelle, sans spéculation ni jugement.
22
+ 2) Forme :
23
+ - Ne pas dépasser {nb_sentences} phrases (phrases complètes, séparées par des points).
24
+ - Ne pas commencer par « Les articles… », « Ces articles… » ni toute méta-introduction.
25
+ - Commencer directement par l’information la plus saillante.
26
+ - Pas de listes, ni de puces ; texte continu.
27
+ - Pas de citations longues ; reformuler brièvement si nécessaire.
28
+ 3) Qualité & Cohérence :
29
+ - Résoudre les divergences entre articles en signalant la divergence de façon concise si pertinente.
30
+ - Éviter les doublons d’information.
31
+ - Ne pas inventer d’informations absentes de l’entrée.
32
+ - Respecter la langue des consignes (français).
33
+
34
+ Sortie attendue :
35
+ - Un seul paragraphe, {nb_sentences} phrases maximum.
36
+ - Aucune introduction, aucune conclusion générique, aucun texte en dehors de la synthèse.
37
+ """
38
+
39
+ EN_USER_SUMMARY_MULTIPLE_DOCS = """
40
+ You are an AI specialized in understanding and synthesizing news articles.
41
+ Your task: produce a concise and faithful summary of the provided content.
42
+
43
+ Inputs:
44
+ - Topic keywords: {keywords}
45
+ - Articles (Title + Content):
46
+ ```{article_list}```
47
+
48
+ Summary requirements:
49
+ 1) Content:
50
+ - Be directly related to the topic evoked by the keywords.
51
+ - Capture the essential, shared, or complementary information across articles.
52
+ - Avoid repetition, minor details, and noise.
53
+ - Include key actors, facts, dates, figures, and stated positions when available.
54
+ - Maintain a neutral, factual tone with no speculation or judgment.
55
+ 2) Form:
56
+ - Do not exceed {nb_sentences} sentences (complete sentences, period-separated).
57
+ - Do not begin with “The articles…”, “These articles…”, or any meta-introduction.
58
+ - Start immediately with the most salient information.
59
+ - No lists or bullets; continuous prose only.
60
+ - No long quotations; paraphrase briefly if needed.
61
+ 3) Quality & Consistency:
62
+ - If articles diverge, briefly note the discrepancy only if relevant.
63
+ - Avoid duplicating the same information.
64
+ - Do not invent information not present in the input.
65
+ - Output in English.
66
+
67
+ Expected output:
68
+ - A single paragraph, at most {nb_sentences} sentences.
69
+ - No introduction, no generic conclusion, and no text outside the summary.
70
+ """
71
+
72
+ # keywords: list of keywords describing the topic
73
+ # article_list: list of articles (each with title and content)
74
+ USER_SUMMARY_MULTIPLE_DOCS = {
75
+ "fr": FR_USER_SUMMARY_MULTIPLE_DOCS,
76
+ "en": EN_USER_SUMMARY_MULTIPLE_DOCS,
77
+ }
78
+
79
+ ###################### TOPIC PROMPTS
80
+
81
+ FR_USER_GENERATE_TOPIC_LABEL_SUMMARIES = """
82
+ Contexte : génération d’une newsletter sur le thème « {newsletter_title} ».
83
+ Tâche : proposer un libellé très court décrivant le sous-thème spécifique du texte fourni.
84
+
85
+ Contraintes :
86
+ - Longueur : au plus 5 mots.
87
+ - Clarté : formulation naturelle, lisible, sans jargon inutile.
88
+ - Spécificité : refléter ce qui rend le texte distinctif dans le cadre du thème « {newsletter_title} ».
89
+ - Éviter :
90
+ - Libellés trop généraux (ex. : « Actualités », « Mise à jour », « Tendances »).
91
+ - Libellés trop proches ou quasi identiques au thème principal (ex. répéter « {newsletter_title} » ou son équivalent).
92
+ - Formulations métadiscursives (« Ce texte… », « Sous-thème… »).
93
+ - Ponctuation superflue (pas de point final si possible).
94
+ - Langue : français.
95
+ - Un seul libellé attendu.
96
+
97
+ Texte :
98
+ "{title_list}"
99
+
100
+ Sortie (uniquement le libellé, sans guillemets, sans texte additionnel) :
101
+ """
102
+
103
+ EN_USER_GENERATE_TOPIC_LABEL_SUMMARIES = """
104
+ Context: generating a newsletter on the topic "{newsletter_title}".
105
+ Task: propose a very short label that captures the specific sub-topic of the provided text.
106
+
107
+ Constraints:
108
+ - Length: maximum 5 words.
109
+ - Clarity: natural, readable phrasing; avoid unnecessary jargon.
110
+ - Specificity: reflect what makes the text distinctive within the scope of "{newsletter_title}".
111
+ - Avoid:
112
+ - Overly general labels (e.g., "News", "Update", "Trends").
113
+ - Labels too close to or nearly identical to the main topic (e.g., repeating "{newsletter_title}" or its near-synonym).
114
+ - Meta-introductions ("This text…", "Subtopic…").
115
+ - Superfluous punctuation (no trailing period if possible).
116
+ - Language: English.
117
+ - Exactly one label expected.
118
+
119
+ Text:
120
+ "{title_list}"
121
+
122
+ Output (only the label, no quotes, no extra text):
123
+ """
124
+
125
+ # title_list: list or block of document excerpts belonging to the topic
126
+ USER_GENERATE_TOPIC_LABEL_SUMMARIES = {
127
+ "fr": FR_USER_GENERATE_TOPIC_LABEL_SUMMARIES,
128
+ "en": EN_USER_GENERATE_TOPIC_LABEL_SUMMARIES,
129
+ }
130
+
131
+ BERTOPIC_FRENCH_TOPIC_REPRESENTATION_PROMPT = (
132
+ "J'ai un topic qui contient les documents suivants :\n"
133
+ "[DOCUMENTS]\n"
134
+ "Le topic est décrit par les mots-clés suivants : [KEYWORDS]\n"
135
+ "Sur la base des informations ci-dessus, extraire une courte étiquette de topic dans le format suivant :\n"
136
+ "Topic : <étiquette du sujet>"
137
+ )
138
+ # Passed directly to BERTopic's OpenAI wrapper, formatted similarly to BERTopic's original prompt which can be found in its source code
@@ -0,0 +1,76 @@
1
+ # Copyright (c) 2024, RTE (https://www.rte-france.com)
2
+ # See AUTHORS.txt
3
+ # SPDX-License-Identifier: MPL-2.0
4
+ # This file is part of BERTrend.
5
+
6
+ TOPIC_DESCRIPTION_PROMPT_EN = """
7
+ You are a topic analysis expert. Your task is to generate a clear, human-readable title and a detailed description for the given topic.
8
+
9
+ Input:
10
+ - Topic representation: {topic_representation}
11
+ - Context documents (may include excerpts, keywords, or summaries):
12
+ {docs_text}
13
+
14
+ Requirements:
15
+ 1) Title:
16
+ - Be concise (max 8 words)
17
+ - Be informative and specific
18
+ - Use Title Case
19
+ - Avoid jargon and buzzwords unless present in the context
20
+
21
+ 2) Description:
22
+ - ~100 words (90–120 words)
23
+ - Summarize the central idea and scope
24
+ - Highlight key themes, entities, or recurring concepts from the context
25
+ - Avoid copying long verbatim text from the context; paraphrase instead
26
+ - Be neutral, factual, and free of speculation
27
+ - Do not begin with generic phrases such as "This theme...", "This topic...", or "The theme...", or "The topic..."
28
+
29
+ 3) Style & Quality:
30
+ - No placeholders, no extraneous commentary
31
+ - No first-person voice
32
+ - No references to the prompt or instructions
33
+ - Start directly with substantive content (e.g., a key concept, scope, or claim), not with meta-introductions
34
+
35
+ Output format (strict JSON; no prose outside JSON):
36
+ "title": "Your title here",
37
+ "description": "Your ~100-word description here."
38
+ """
39
+
40
+ TOPIC_DESCRIPTION_PROMPT_FR = """
41
+ Vous êtes un expert en analyse de sujets. Votre tâche est de générer un titre clair et lisible ainsi qu’une description détaillée pour le sujet fourni.
42
+
43
+ Entrée :
44
+ - Représentation du sujet : {topic_representation}
45
+ - Contexte (extraits, mots-clés ou résumés) :
46
+ {docs_text}
47
+
48
+ Exigences :
49
+ 1) Titre :
50
+ - Concis (max. 8 mots)
51
+ - Informatif et spécifique
52
+ - Éviter le jargon sauf s’il apparaît dans le contexte
53
+
54
+ 2) Description :
55
+ - Environ 100 mots (90–120)
56
+ - Résumer l’idée centrale et le périmètre
57
+ - Mettre en avant les thèmes, entités ou concepts récurrents du contexte
58
+ - Ne pas copier de longs passages ; reformuler
59
+ - Ton neutre, factuel, sans spéculation
60
+ - Ne pas commencer par des formules génériques telles que « Ce thème… », « Ce sujet… » ou « Le thème… » ou « Le sujet… »
61
+
62
+ 3) Style & Qualité :
63
+ - Pas d’espaces réservés, pas de commentaires superflus
64
+ - Pas de première personne
65
+ - Aucune référence aux instructions
66
+ - Commencer directement par le contenu substantiel (concept clé, périmètre, ou idée centrale), sans méta-introduction
67
+
68
+ Format de sortie (JSON strict ; aucun texte hors du JSON) :
69
+ "title": "Votre titre ici",
70
+ "description": "Votre description (~100 mots) ici."
71
+ """
72
+
73
+ TOPIC_DESCRIPTION_PROMPT = {
74
+ "en": TOPIC_DESCRIPTION_PROMPT_EN,
75
+ "fr": TOPIC_DESCRIPTION_PROMPT_FR,
76
+ }
@@ -0,0 +1,308 @@
1
+ # Copyright (c) 2024, RTE (https://www.rte-france.com)
2
+ # See AUTHORS.txt
3
+ # SPDX-License-Identifier: MPL-2.0
4
+ # This file is part of BERTrend.
5
+ import os
6
+ from datetime import datetime
7
+ from pathlib import Path
8
+
9
+ from jinja2 import Template, Environment, FileSystemLoader
10
+ from loguru import logger
11
+
12
+ from bertrend import OUTPUT_PATH
13
+ from bertrend.trend_analysis.data_structure import TopicSummaryList, SignalAnalysis
14
+
15
+ # Global variables for prompts
16
+ SIGNAL_INTRO = {
17
+ "en": """As an elite strategic foresight analyst with extensive expertise across multiple domains and industries, your task is to conduct a comprehensive evaluation of a potential signal derived from the following topic summary:
18
+
19
+ {summary_from_first_prompt}
20
+
21
+ Leverage your knowledge and analytical skills to provide an in-depth analysis of this signal's potential impact and evolution:
22
+ """,
23
+ "fr": """En tant qu'analyste de prospective stratégique d'élite avec une expertise étendue dans de multiples domaines et industries, votre tâche est de mener une évaluation complète d'un signal potentiel dérivé du résumé de sujet suivant :
24
+
25
+ {summary_from_first_prompt}
26
+
27
+ Utilisez vos connaissances et compétences analytiques pour fournir une analyse approfondie de l'impact potentiel et de l'évolution de ce signal :
28
+ """,
29
+ }
30
+
31
+ SIGNAL_INSTRUCTIONS = {
32
+ "en": """
33
+ Analyze this signal only if the input data is sufficiently complete and substantive. If the subject summary lacks completeness, substance, specificity, or novelty, respond with an empty JSON dictionary: {}
34
+
35
+ === DECISION RULES (STRICT SUFFICIENCY) ===
36
+ - Overall Sufficiency: Proceed with analysis only if the topic summary contains enough concrete, non-trivial information to support evidence-based reasoning across at least one analysis dimension (Impact, Evolution, Interconnections, Drivers/Inhibitors).
37
+ - Section Sufficiency: For each analysis section (Impact, Evolution Scenarios, Interconnections and Synergies, Drivers and Inhibitors), include the section ONLY if the input contains enough detail to meet the Minimum Quality Requirements. If not, omit the section entirely (do not include placeholders).
38
+ - Evidence-First: Prefer omission over speculation. Do not infer facts not supported by the provided summary.
39
+
40
+ For substantial signals, provide the following sections (include only those that meet the standards; omit any that do not):
41
+
42
+ 1. Potential Impact Analysis:
43
+ - Examine potential effects on sectors, industries, and societal aspects.
44
+ - Cover immediate (1–2 years), medium (3–5 years), and long-term (5–10 years) horizons.
45
+ - Include ripple effects and second-order consequences when supportable.
46
+
47
+ 2. Evolution Scenarios:
48
+ - Describe plausible future developments and manifestation paths.
49
+ - Identify factors shaping the trajectory.
50
+ - Provide both optimistic and pessimistic scenarios only if both are sufficiently supported; otherwise include the supported one(s) and omit the rest.
51
+
52
+ 3. Interconnections and Synergies:
53
+ - Identify interactions with current trends or emerging phenomena.
54
+ - Discuss synergies or conflicts with existing systems or paradigms.
55
+
56
+ 4. Drivers and Inhibitors:
57
+ - Analyze accelerants and amplifiers of the signal.
58
+ - Examine barriers, constraints, or resistances.
59
+
60
+ Your analysis should be thorough and nuanced, going beyond surface-level observations, and grounded in the provided content. Make well-reasoned predictions only when they are logically supported by the input. If analysis cannot be substantiated with clear reasoning, omit that section.
61
+
62
+ === OUTPUT QUALITY STANDARDS ===
63
+ Avoid:
64
+ - Vague generalizations
65
+ - Obvious conclusions without new insight
66
+ - Insufficient evidence
67
+ - Generic observations
68
+ - Circular reasoning
69
+ - Superficial treatment
70
+ - Unsubstantiated speculation
71
+ - Outdated perspectives
72
+
73
+ === MINIMUM QUALITY REQUIREMENTS (APPLY PER SECTION) ===
74
+ Each included section must demonstrate at least 2 of:
75
+ - Specific Context: Clear temporal, geographic, or sectoral boundaries with examples
76
+ - Concrete Evidence: Quantifiable insights, verifiable examples, or substantiated claims from the input
77
+ - Novel Perspectives: Non-obvious connections or emerging patterns grounded in the input
78
+ - Actionable Intelligence: Guidance that enables decision-making or planning
79
+ - Cross-Domain Impact: Implications across multiple sectors or domains
80
+ - Measurable Dimensions: Metrics, indicators, or tracking mechanisms
81
+ - Causal Analysis: Clear cause-and-effect or contributing factors
82
+ - Strategic Relevance: Direct link to business, policy, or societal decisions
83
+
84
+ === OUTPUT REQUIREMENTS ===
85
+ - Section-Level Omission: Omit any section that cannot meet the Minimum Quality Requirements with the provided information.
86
+ - Evidence-Based: Use specific, quantifiable language with concrete examples derived from the input.
87
+ - Confidence Levels: Clearly distinguish high-confidence assessments from speculative insights.
88
+ - Decision-Focused: Prioritize actionable intelligence for strategic decision-makers.
89
+ - Balanced Objectivity: Maintain rigor while acknowledging uncertainties and limitations.
90
+ - Temporal Structure: Organize insights across immediate (1–2 years), medium (3–5 years), and long-term (5–10 years) where applicable.
91
+ - Final Validation: Before finalizing, remove any statement that cannot be traced to or logically derived from the provided summary.
92
+
93
+ If no section can meet these standards, return an empty JSON dictionary: {}
94
+ """,
95
+ "fr": """
96
+ Analysez ce signal uniquement si les données d’entrée sont suffisamment complètes et substantielles. Si le résumé du sujet manque de complétude, de substance, de spécificité ou de nouveauté, répondez avec un dictionnaire JSON vide : {}
97
+
98
+ === RÈGLES DE DÉCISION (SUFFISANCE STRICTE) ===
99
+ - Suffisance Globale : Poursuivez l’analyse uniquement si le résumé contient des informations concrètes et non triviales permettant un raisonnement fondé sur des preuves pour au moins une dimension d’analyse (Impact, Évolution, Interconnexions, Moteurs/Inhibiteurs).
100
+ - Suffisance par Section : Pour chaque section (Impact, Scénarios d’Évolution, Interconnexions et Synergies, Moteurs et Inhibiteurs), incluez la section UNIQUEMENT si les informations permettent d’atteindre les Exigences Minimales de Qualité. Sinon, omettez entièrement la section (pas d’espace réservé).
101
+ - Primauté des Preuves : Préférez l’omission à la spéculation. N’inférez pas de faits non étayés par le résumé fourni.
102
+
103
+ Pour les signaux substantiels, fournissez les sections suivantes (n’incluez que celles qui respectent les standards ; omettez celles qui ne les atteignent pas) :
104
+
105
+ 1. Analyse de l’Impact Potentiel :
106
+ - Effets potentiels sur secteurs, industries et aspects sociétaux.
107
+ - Couvrez les horizons immédiat (1–2 ans), moyen (3–5 ans) et long terme (5–10 ans).
108
+ - Incluez les effets d’entraînement et de second ordre lorsque c’est étayé.
109
+
110
+ 2. Scénarios d’Évolution :
111
+ - Décrivez des développements plausibles et voies de manifestation futures.
112
+ - Identifiez les facteurs influençant la trajectoire.
113
+ - Fournissez des scénarios optimistes et pessimistes uniquement si tous deux sont suffisamment étayés ; sinon, incluez seulement ceux qui le sont et omettez le reste.
114
+
115
+ 3. Interconnexions et Synergies :
116
+ - Interactions avec les tendances actuelles ou phénomènes émergents.
117
+ - Synergies ou conflits avec les systèmes ou paradigmes existants.
118
+
119
+ 4. Moteurs et Inhibiteurs :
120
+ - Facteurs accélérateurs/amplificateurs du signal.
121
+ - Obstacles, contraintes ou résistances.
122
+
123
+ Votre analyse doit être approfondie, nuancée et ancrée dans le contenu fourni. Proposez des prédictions bien raisonnées uniquement lorsqu’elles sont logiquement étayées par l’entrée. Si une section ne peut être étayée par un raisonnement clair, omettez-la.
124
+
125
+ === STANDARDS DE QUALITÉ DE SORTIE ===
126
+ À éviter :
127
+ - Généralisations vagues
128
+ - Conclusions évidentes sans nouveaux éclairages
129
+ - Preuves insuffisantes
130
+ - Observations génériques
131
+ - Raisonnement circulaire
132
+ - Traitement superficiel
133
+ - Spéculation non étayée
134
+ - Perspectives obsolètes
135
+
136
+ === EXIGENCES MINIMALES DE QUALITÉ (PAR SECTION) ===
137
+ Chaque section incluse doit démontrer au moins 2 des éléments suivants :
138
+ - Contexte Spécifique : Limites temporelles, géographiques ou sectorielles claires avec exemples
139
+ - Preuves Concrètes : Insights quantifiables, exemples vérifiables, ou affirmations étayées par l’entrée
140
+ - Perspectives Nouvelles : Connexions non évidentes ou schémas émergents ancrés dans l’entrée
141
+ - Intelligence Actionnable : Conseils permettant la décision ou la planification
142
+ - Impact Trans-Domaine : Implications multi-sectorielles
143
+ - Dimensions Mesurables : Métriques, indicateurs ou mécanismes de suivi
144
+ - Analyse Causale : Relations de cause à effet ou facteurs contributifs clairs
145
+ - Pertinence Stratégique : Lien direct avec décisions business, politiques ou sociétales
146
+
147
+ === EXIGENCES DE SORTIE ===
148
+ - Omission par Section : Omettez toute section qui ne peut atteindre les exigences minimales avec les informations disponibles.
149
+ - Basé sur les Preuves : Utilisez un langage spécifique et quantifiable avec des exemples concrets tirés de l’entrée.
150
+ - Niveaux de Confiance : Distinguez clairement les évaluations à haute confiance des insights spéculatifs.
151
+ - Orienté Décision : Priorisez l’intelligence actionnable pour les décideurs stratégiques.
152
+ - Objectivité Équilibrée : Rigueur analytique en reconnaissant les incertitudes et limitations.
153
+ - Structure Temporelle : Organisez les insights sur les horizons immédiat (1–2 ans), moyen (3–5 ans) et long terme (5–10 ans) lorsque pertinent.
154
+ - Validation Finale : Avant de finaliser, retirez toute affirmation qui ne peut être retracée ou logiquement dérivée du résumé fourni.
155
+
156
+ Si aucune section ne peut respecter ces standards, renvoyez un dictionnaire JSON vide : {}
157
+ """,
158
+ }
159
+
160
+ TOPIC_SUMMARY_PROMPT = {
161
+ "en": """
162
+ As an expert analyst specializing in trend analysis and strategic foresight, your task is to provide a comprehensive evolution summary of Topic {topic_number}. Use only the information provided below:
163
+
164
+ {content_summary}
165
+
166
+ Structure your analysis as follows:
167
+
168
+ For the first timestamp:
169
+
170
+ ## [Concise yet impactful title capturing the essence of the topic at this point]
171
+ ### Date: [Relevant date or time frame - format %Y-%m-%d]
172
+ ### Key Developments
173
+ - [Bullet point summarizing a major development or trend]
174
+ - [Additional bullet points as needed]
175
+
176
+ ### Analysis
177
+ [2-3 sentences maximum providing deeper insights into the developments, their potential implications, and their significance in the broader context of the topic's evolution]
178
+
179
+ For all subsequent timestamps:
180
+
181
+ ## [Concise yet impactful title capturing the essence of the topic at this point]
182
+ ### Date: [Relevant date or time frame - format %Y-%m-%d]
183
+ ### Key Developments
184
+ - [Bullet point summarizing a major development or trend]
185
+ - [Additional bullet points as needed]
186
+
187
+ ### Analysis
188
+ [2-3 sentences maximum providing deeper insights into the developments, their potential implications, and their significance in the broader context of the topic's evolution]
189
+
190
+ ### What's New
191
+ [1-2 sentences maximum highlighting how this period differs from the previous one, focusing on new elements or significant changes]
192
+
193
+ Provide your analysis using only this format, based solely on the information given. Do not include any additional summary or overview sections beyond what is specified in this structure.
194
+ """,
195
+ "fr": """
196
+ En tant qu'analyste expert spécialisé dans l'analyse des tendances et la prospective stratégique, votre tâche est de fournir un résumé complet de l'évolution du Sujet {topic_number}. Utilisez uniquement les informations fournies ci-dessous :
197
+
198
+ {content_summary}
199
+
200
+ Structurez votre analyse comme suit :
201
+
202
+ Pour le premier timestamp :
203
+
204
+ ## [Titre concis mais percutant capturant l'essence du sujet à ce moment]
205
+ ### Date : [Date ou période pertinente - format %Y-%m-%d]
206
+ ### Développements Clés
207
+ - [Point résumant un développement majeur ou une tendance]
208
+ - [Points supplémentaires si nécessaire]
209
+
210
+ ### Analyse
211
+ [2-3 phrases maximum fournissant des insights plus profonds sur les développements, leurs implications potentielles et leur importance dans le contexte plus large de l'évolution du sujet]
212
+
213
+ Pour tous les timestamps suivants :
214
+
215
+ ## [Titre concis mais percutant capturant l'essence du sujet à ce moment]
216
+ ### Date : [Date ou période pertinente - format %Y-%m-%d]
217
+ ### Développements Clés
218
+ - [Point résumant un développement majeur ou une tendance]
219
+ - [Points supplémentaires si nécessaire]
220
+
221
+ ### Analyse
222
+ [2-3 phrases maximum fournissant des insights plus profonds sur les développements, leurs implications potentielles et leur importance dans le contexte plus large de l'évolution du sujet]
223
+
224
+ ### Nouveautés
225
+ [1-2 phrases maximum soulignant en quoi cette période diffère de la précédente, en se concentrant sur les nouveaux éléments ou les changements significatifs]
226
+
227
+ Fournissez votre analyse en utilisant uniquement ce format, basé uniquement sur les informations données. N'incluez pas de sections de résumé ou d'aperçu supplémentaires au-delà de ce qui est spécifié dans cette structure.
228
+ """,
229
+ }
230
+
231
+
232
+ def get_prompt(
233
+ language: str,
234
+ prompt_type: str,
235
+ topic_number: int = None,
236
+ content_summary: str = None,
237
+ summary_from_first_prompt: str = None,
238
+ ):
239
+ lang = "en" if language == "English" else "fr"
240
+
241
+ if prompt_type == "weak_signal":
242
+ prompt = (
243
+ SIGNAL_INTRO[lang].format(
244
+ summary_from_first_prompt=summary_from_first_prompt
245
+ )
246
+ + SIGNAL_INSTRUCTIONS[lang]
247
+ )
248
+
249
+ elif prompt_type == "topic_summary":
250
+ prompt = TOPIC_SUMMARY_PROMPT[lang].format(
251
+ topic_number=topic_number, content_summary=content_summary
252
+ )
253
+ else:
254
+ raise ValueError(f"Unsupported prompt type: {prompt_type}")
255
+
256
+ return prompt
257
+
258
+
259
+ def save_html_output(html_output, output_file="signal_llm.html"):
260
+ """Function to save the model's output as HTML"""
261
+ output_path = OUTPUT_PATH / output_file
262
+
263
+ # Save the cleaned HTML
264
+ with open(output_path, "w", encoding="utf-8") as file:
265
+ file.write(html_output)
266
+ logger.debug(f"Cleaned HTML output saved to {output_path}")
267
+
268
+
269
+ def fill_html_template(
270
+ topic_summary_list: TopicSummaryList,
271
+ signal_analysis: SignalAnalysis,
272
+ language: str = "fr",
273
+ ) -> str:
274
+ """Fill the HTML template with appropriate data"""
275
+ # Setup Jinja2 environment
276
+ template_dir = os.path.dirname(os.path.abspath(__file__))
277
+ env = Environment(
278
+ loader=FileSystemLoader(template_dir),
279
+ )
280
+ template = env.get_template(
281
+ "signal_llm_template_en.html"
282
+ if language == "en"
283
+ else "signal_llm_template_fr.html"
284
+ )
285
+
286
+ # Sort the list by date from most recent to least recent
287
+ try:
288
+ sorted_topic_summary_by_time_period = sorted(
289
+ topic_summary_list.topic_summary_by_time_period,
290
+ key=lambda x: datetime.strptime(x.date, "%Y-%m-%d"),
291
+ reverse=True,
292
+ )
293
+ topic_summary_list.topic_summary_by_time_period = (
294
+ sorted_topic_summary_by_time_period
295
+ )
296
+ except Exception as e:
297
+ logger.warning("Cannot sort summaries by date, probably wrong date format")
298
+
299
+ # Render the template with the provided data
300
+ rendered_html = template.render(
301
+ topic_summary_list=topic_summary_list, signal_analysis=signal_analysis
302
+ )
303
+
304
+ # FIXME: many \n are added...
305
+ rendered_html = rendered_html.replace("\n", "")
306
+ rendered_html = rendered_html.replace("\\'", "'")
307
+
308
+ return rendered_html
@@ -360,6 +360,10 @@ TRANSLATIONS = {
360
360
  "en": "Error sending email",
361
361
  },
362
362
  # Success Messages
363
+ "email_being_sent": {
364
+ "fr": "Email en cours d'envoi...",
365
+ "en": "Email being sent...",
366
+ },
363
367
  "email_sent_successfully": {
364
368
  "fr": "Email envoyé avec succès!",
365
369
  "en": "Email sent successfully!",
@@ -17,7 +17,7 @@ def generate_bertrend_topic_description(
17
17
  """Generates a LLM-based human-readable description of a topic composed of a title and a description (as a dict)"""
18
18
  if not texts:
19
19
  logger.warning(f"No text found for topic number {topic_number}")
20
- return None
20
+ return None, None
21
21
 
22
22
  topic_representation = ", ".join(topic_words.split("_")) # Get top 10 words
23
23
 
@@ -312,6 +312,7 @@ def email(temp_path: Path, mail_title: str, recipients: list[str]) -> None:
312
312
  with open(temp_path, "r") as file:
313
313
  # Read the entire contents of the file into a string
314
314
  # content = file.read()
315
+ st.info(translate("email_being_sent"))
315
316
  send_email(
316
317
  credentials=credentials,
317
318
  subject=mail_title,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "bertrend"
3
- version = "0.3.16"
3
+ version = "0.3.17"
4
4
  description = "BERTrend analyses topic evolution over time using state-of-the-art transformer models: topic modelling and LLM"
5
5
  license = "LICENSE.md"
6
6
  readme = "README.md"
@@ -1,94 +0,0 @@
1
- # Copyright (c) 2024, RTE (https://www.rte-france.com)
2
- # See AUTHORS.txt
3
- # SPDX-License-Identifier: MPL-2.0
4
- # This file is part of BERTrend.
5
- from bertrend.config.parameters import BERTOPIC_SERIALIZATION
6
-
7
- FR_USER_SUMMARY_MULTIPLE_DOCS = (
8
- "Vous êtes une IA hautement qualifiée, formée à la compréhension et à la synthèse du langage. "
9
- "Voici ci-dessous plusieurs articles de presse (Titre et Contenu). "
10
- "Tous les articles appartiennent au même thème représenté par les mots-clés suivants : {keywords}. "
11
- "Générez une synthèse en {nb_sentences} phrases maximum de ces articles qui doit être en lien avec le thème évoqué par les mots-clés. "
12
- "La synthèse doit permettre de donner une vision d'ensemble du thème sans lire les articles. "
13
- "Ne pas commencer par 'Les articles...' mais commencer directement la synthèse.\n"
14
- "Liste des articles :\n"
15
- "```{article_list}```\n"
16
- "Synthèse :"
17
- )
18
-
19
- EN_USER_SUMMARY_MULTIPLE_DOCS = (
20
- "You are a highly qualified AI, trained in language understanding and synthesis. "
21
- "Below are several press articles (Title and Content). "
22
- "All the articles belong to the same topic represented by the following keywords: {keywords}. "
23
- "Generate a summary of these articles, which must be related to the theme evoked by the keywords. "
24
- "The summary must not exceed {nb_sentences} sentences and should include the essential information from the articles.\n"
25
- "List of articles :\n"
26
- "```{article_list}```\n"
27
- "Summary :"
28
- )
29
- # keywords: list of keywords describing the topic
30
- # list of articles and their title
31
- USER_SUMMARY_MULTIPLE_DOCS = {
32
- "fr": FR_USER_SUMMARY_MULTIPLE_DOCS,
33
- "en": EN_USER_SUMMARY_MULTIPLE_DOCS,
34
- }
35
-
36
- ###################### TOPIC PROMPTS
37
-
38
- FR_USER_GENERATE_TOPIC_LABEL_SUMMARIES = (
39
- "Décrit en une courte expression le thème associé à l'ensemble des extraits "
40
- "suivants. Le thème doit être court et spécifique en 4 mots maximum. "
41
- '\n"{title_list}"'
42
- )
43
-
44
- EN_USER_GENERATE_TOPIC_LABEL_SUMMARIES = (
45
- "Describe in a short sentence the topic associated with the following extracts. "
46
- "The topic description should be short and specific, no more than 4 words. "
47
- '\n"{title_list}"'
48
- )
49
-
50
- FR_USER_GENERATE_TOPIC_LABEL_SUMMARIES_V2 = (
51
- 'Dans le cadre de la génération d\'une newsletter sur le thème "{newsletter_title}", '
52
- "décrit en une courte expression le sous-thème associé au texte suivant. "
53
- "L'expression doit être courte en 4 mots maximum. "
54
- "Elle doit montrer en quoi le texte est spécifique pour le thème. "
55
- "Elle ne doit pas être générale ni décrire un sous-thème trop proche du thème de la newsletter.\n\n"
56
- 'Texte : "{title_list}"'
57
- )
58
-
59
- # title_list: list of documents extracts belonging to the topic
60
-
61
- EN_USER_GENERATE_TOPIC_LABEL_SUMMARIES_V2 = (
62
- 'Within the framework of the generation of a newsletter on the topic "{newsletter_title}", '
63
- "describe in a short sentence the sub-topic associated with the following text. "
64
- "The sentence should be short, no more than 4 words. "
65
- "It should show in what way the text is specific to the topic. "
66
- "It should not be general nor describe a sub-topic too close to the topic of the newsletter.\n\n"
67
- '\n"{title_list}"'
68
- )
69
- # title_list: list of documents extracts belonging to the topic
70
-
71
- USER_GENERATE_TOPIC_LABEL_SUMMARIES = {
72
- "fr": FR_USER_GENERATE_TOPIC_LABEL_SUMMARIES_V2,
73
- "en": EN_USER_GENERATE_TOPIC_LABEL_SUMMARIES_V2,
74
- }
75
-
76
-
77
- FR_USER_GENERATE_TOPIC_LABEL_TITLE = (
78
- "Vous êtes une IA hautement qualifiée, formée à la compréhension et à la synthèse du langage. "
79
- 'Après utilisation d\'un algorithme de topic modelling, un topic est représenté par les mots-clé suivants : """{keywords}.""" '
80
- 'Le topic contient plusieurs documents dont les titres sont les suivants :\n"""\n{title_list}\n"""\n'
81
- "À partir de ces informations sur le topic, écrivez un titre court de ce topic en 3 mots maximum. "
82
- )
83
- # keywords: list of keywords describing the topic
84
- # title_list: list of documents title belonging to the topic
85
-
86
-
87
- BERTOPIC_FRENCH_TOPIC_REPRESENTATION_PROMPT = (
88
- "J'ai un topic qui contient les documents suivants :\n"
89
- "[DOCUMENTS]\n"
90
- "Le topic est décrit par les mots-clés suivants : [KEYWORDS]\n"
91
- "Sur la base des informations ci-dessus, extraire une courte étiquette de topic dans le format suivant :\n"
92
- "Topic : <étiquette du sujet>"
93
- )
94
- # Passed directly to BERTopic's OpenAI wrapper, formatted similarly to BERTopic's original prompt which can be found in its source code