forecasting-tools 0.2.91__tar.gz → 0.3.0__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 (229) hide show
  1. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/PKG-INFO +54 -21
  2. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/README.md +32 -10
  3. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/__init__.py +85 -23
  4. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/ai_congress_v2/congress_orchestrator.py +1 -1
  5. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/ai_congress_v2/data_models.py +1 -1
  6. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/ai_congress_v2/member_profiles.py +27 -23
  7. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/base_rates/deduplicator.py +12 -4
  8. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/other/data_analyzer.py +2 -2
  9. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/question_generators/question_decomposer.py +3 -3
  10. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/question_generators/topic_generator.py +3 -0
  11. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/research/computer_use.py +16 -4
  12. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/agent_runner.py +1 -1
  13. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/data_models.py +1 -1
  14. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/intervention_testing/intervention_policy_agent.py +1 -1
  15. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/intervention_testing/intervention_runner.py +1 -1
  16. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/situation_generator.py +2 -2
  17. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/README.md +285 -0
  18. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/__init__.py +56 -0
  19. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/benchmark.py +459 -0
  20. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/canonicalize.py +119 -0
  21. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/catalog.py +571 -0
  22. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/cli.py +353 -0
  23. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/config.py +88 -0
  24. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/content_store.py +323 -0
  25. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/cost.py +137 -0
  26. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/coverage.py +237 -0
  27. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/fetchers/__init__.py +138 -0
  28. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/fetchers/base.py +25 -0
  29. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/fetchers/cloakbrowser_fetcher.py +62 -0
  30. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/fetchers/firecrawl_fetcher.py +122 -0
  31. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/fetchers/hyperbrowser_fetcher.py +149 -0
  32. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/fetchers/pdf_fetcher.py +146 -0
  33. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/fetchers/playwright_fetcher.py +254 -0
  34. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/fetchers/tiered.py +56 -0
  35. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/ingest/__init__.py +30 -0
  36. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/ingest/trace_extraction.py +379 -0
  37. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/ingest/url_extraction.py +133 -0
  38. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/layout.py +62 -0
  39. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/manifest.py +100 -0
  40. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/models.py +97 -0
  41. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/pipeline.py +317 -0
  42. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/quality.py +56 -0
  43. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/reindex.py +278 -0
  44. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/reports.py +93 -0
  45. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/storage/__init__.py +13 -0
  46. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/storage/blob_store.py +25 -0
  47. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/storage/local_store.py +34 -0
  48. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/storage/s3_store.py +66 -0
  49. forecasting_tools-0.3.0/forecasting_tools/agents_and_tools/source_archive/viewer.py +416 -0
  50. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/agent_wrappers.py +9 -4
  51. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/general_llm.py +62 -15
  52. forecasting_tools-0.3.0/forecasting_tools/calibration_adjustment/__init__.py +23 -0
  53. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/calibration_adjustment/constant_shift_adjuster.py +2 -2
  54. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/calibration_adjustment/decision_tree_adjuster.py +2 -2
  55. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/calibration_adjustment/k_means_adjuster.py +2 -2
  56. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/calibration_adjustment/logistic_recalibration_adjuster.py +2 -2
  57. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/calibration_adjustment/step_adjuster.py +2 -2
  58. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/cp_benchmarking/benchmark_displayer.py +11 -4
  59. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/bot_lists.py +4 -0
  60. forecasting_tools-0.3.0/forecasting_tools/forecast_bots/official_bots/no_research_one_shot_bot.py +185 -0
  61. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/template_bot_2026_summer.py +30 -0
  62. forecasting_tools-0.3.0/forecasting_tools/front_end/__init__.py +5 -0
  63. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/chat_page.py +9 -6
  64. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/congress_v2_page.py +6 -6
  65. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/forecaster_page.py +95 -7
  66. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/helpers/asknews_searcher.py +10 -18
  67. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/helpers/metaculus_client.py +4 -1
  68. forecasting_tools-0.3.0/forecasting_tools/util/optional_imports.py +24 -0
  69. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/util/stats.py +298 -293
  70. forecasting_tools-0.3.0/pyproject.toml +92 -0
  71. forecasting_tools-0.2.91/forecasting_tools/calibration_adjustment/__init__.py +0 -18
  72. forecasting_tools-0.2.91/pyproject.toml +0 -69
  73. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/LICENSE +0 -0
  74. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/__init__.py +0 -0
  75. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/ai_congress_v2/__init__.py +0 -0
  76. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/ai_congress_v2/congress_member_agent.py +0 -0
  77. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/ai_congress_v2/tools.py +0 -0
  78. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/base_rates/base_rate_researcher.py +0 -0
  79. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/base_rates/estimator.py +0 -0
  80. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/base_rates/niche_list_researcher.py +0 -0
  81. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/deprecated/configured_llms.py +0 -0
  82. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/deprecated/general_researcher.py +0 -0
  83. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/deprecated/question_generator.py +0 -0
  84. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/deprecated/question_responder.py +0 -0
  85. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/deprecated/question_router.py +0 -0
  86. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/deprecated/research_coordinator.py +0 -0
  87. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/minor_tools.py +0 -0
  88. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/other/hosted_file.py +0 -0
  89. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/question_generators/generated_question.py +0 -0
  90. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/question_generators/harmful_question_identifier.py +0 -0
  91. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/question_generators/q3_q4_quarterly_questions.json +0 -0
  92. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/question_generators/question_operationalizer.py +0 -0
  93. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/question_generators/simple_question.py +0 -0
  94. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/research/find_a_dataset.py +0 -0
  95. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/research/key_factors_researcher.py +0 -0
  96. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/research/smart_searcher.py +0 -0
  97. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/__init__.py +0 -0
  98. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/effect_engine.py +0 -0
  99. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/example_situations/industrial_basin.json +0 -0
  100. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/example_situations/milbrook.json +0 -0
  101. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/example_situations/simple_business.json +0 -0
  102. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/example_situations/simple_dnd.json +0 -0
  103. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/example_situations/simple_election.json +0 -0
  104. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/example_situations/willowbrook.json +0 -0
  105. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/example_situations/z_broken_mafia.json +0 -0
  106. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/intervention_testing/__init__.py +0 -0
  107. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/intervention_testing/data_models.py +0 -0
  108. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/intervention_testing/forecast_resolver.py +0 -0
  109. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/intervention_testing/intervention_storage.py +0 -0
  110. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/agents_and_tools/situation_simulator/simulator.py +0 -0
  111. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/__init__.py +0 -0
  112. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/ai_utils/__init__.py +0 -0
  113. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/ai_utils/openai_utils.py +0 -0
  114. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/ai_utils/response_types.py +0 -0
  115. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/deprecated_model_classes/README.md +0 -0
  116. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/deprecated_model_classes/claude35sonnet.py +0 -0
  117. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/deprecated_model_classes/deepseek_r1.py +0 -0
  118. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/deprecated_model_classes/gpt4o.py +0 -0
  119. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/deprecated_model_classes/gpt4ovision.py +0 -0
  120. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/deprecated_model_classes/gpto1.py +0 -0
  121. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/deprecated_model_classes/gpto1preview.py +0 -0
  122. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/deprecated_model_classes/metaculus4o.py +0 -0
  123. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/deprecated_model_classes/perplexity.py +0 -0
  124. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/exa_searcher.py +0 -0
  125. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/__init__.py +0 -0
  126. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/ai_model.py +0 -0
  127. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/combined_llm_archetype.py +0 -0
  128. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/incurs_cost.py +0 -0
  129. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/named_model.py +0 -0
  130. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/outputs_text.py +0 -0
  131. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/priced_per_request.py +0 -0
  132. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/request_limited_model.py +0 -0
  133. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/retryable_model.py +0 -0
  134. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/time_limited_model.py +0 -0
  135. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/token_limited_model.py +0 -0
  136. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/tokens_are_calculatable.py +0 -0
  137. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_interfaces/tokens_incur_cost.py +0 -0
  138. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/model_tracker.py +0 -0
  139. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/resource_managers/__init__.py +0 -0
  140. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/resource_managers/hard_limit_manager.py +0 -0
  141. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/resource_managers/monetary_cost_manager.py +0 -0
  142. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/ai_models/resource_managers/refreshing_bucket_rate_limiter.py +0 -0
  143. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/auto_optimizers/bot_evaluator.py +0 -0
  144. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/auto_optimizers/bot_optimizer.py +0 -0
  145. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/auto_optimizers/control_prompt.py +0 -0
  146. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/auto_optimizers/customizable_bot.py +0 -0
  147. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/auto_optimizers/prompt_data_models.py +0 -0
  148. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/auto_optimizers/prompt_optimizer.py +0 -0
  149. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/auto_optimizers/question_plus_research.py +0 -0
  150. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/calibration_adjustment/.gitignore +0 -0
  151. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/calibration_adjustment/_training_data.py +0 -0
  152. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/calibration_adjustment/benchmark.ipynb +0 -0
  153. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/calibration_adjustment/calibration_adjuster.py +0 -0
  154. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/cp_benchmarking/benchmark_for_bot.py +0 -0
  155. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/cp_benchmarking/benchmarker.py +0 -0
  156. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/__init__.py +0 -0
  157. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/binary_report.py +0 -0
  158. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/coherence_link.py +0 -0
  159. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/conditional_models.py +0 -0
  160. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/conditional_report.py +0 -0
  161. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/data_organizer.py +0 -0
  162. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/forecast_report.py +0 -0
  163. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/markdown_tree.py +0 -0
  164. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/multiple_choice_report.py +0 -0
  165. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/numeric_report.py +0 -0
  166. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/questions.py +0 -0
  167. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/timestamped_predictions.py +0 -0
  168. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/data_models/user_response.py +0 -0
  169. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/__init__.py +0 -0
  170. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/__init__.py +0 -0
  171. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q1_veritas_bot.py +0 -0
  172. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q1t_w_convert_to_binary.py +0 -0
  173. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q1t_w_personas_and_exa.py +0 -0
  174. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q2t_w_decomposition.py +0 -0
  175. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q3t_w_asknews.py +0 -0
  176. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q3t_w_exa.py +0 -0
  177. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q3t_w_q4vbinary.py +0 -0
  178. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q4_veritas_bot.py +0 -0
  179. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q4v_w_exa.py +0 -0
  180. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q4v_w_exa_and_dseekr1.py +0 -0
  181. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/experiments/q4v_w_exa_and_o1_preview.py +0 -0
  182. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/forecast_bot.py +0 -0
  183. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/main_bot.py +0 -0
  184. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/__init__.py +0 -0
  185. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/gpt_4_1_optimized_bot.py +0 -0
  186. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/q1_template_bot.py +0 -0
  187. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/q2_template_bot.py +0 -0
  188. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/q3_template_bot.py +0 -0
  189. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/q4_template_bot.py +0 -0
  190. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/research_only_bot_2025_fall.py +0 -0
  191. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/template_bot_2025_fall.py +0 -0
  192. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/template_bot_2026_spring.py +0 -0
  193. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/official_bots/uniform_probability_bot.py +0 -0
  194. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/forecast_bots/template_bot.py +0 -0
  195. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/Home.py +0 -0
  196. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/base_rate_page.py +0 -0
  197. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/benchmark_page.py +0 -0
  198. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/csv_agent.py +0 -0
  199. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/estimator_page.py +0 -0
  200. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/intervention_leaderboard_page.py +0 -0
  201. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/key_factors_page.py +0 -0
  202. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/niche_list_researcher_page.py +0 -0
  203. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/app_pages/simulator_page.py +0 -0
  204. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/example_outputs/base_rate_page_examples.json +0 -0
  205. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/example_outputs/congress_page_example.json +0 -0
  206. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/example_outputs/congress_v2_page_example.json +0 -0
  207. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/example_outputs/estimator_page_examples.json +0 -0
  208. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/example_outputs/forecast_page_examples.json +0 -0
  209. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/example_outputs/key_factors_page_examples.json +0 -0
  210. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/example_outputs/niche_list_page_examples.json +0 -0
  211. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/example_outputs/question_generator_page_examples.json +0 -0
  212. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/helpers/app_page.py +0 -0
  213. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/helpers/custom_auth.py +0 -0
  214. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/helpers/report_displayer.py +0 -0
  215. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/front_end/helpers/tool_page.py +0 -0
  216. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/helpers/__init__.py +0 -0
  217. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/helpers/asknews_cache.py +0 -0
  218. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/helpers/forecast_database_manager.py +0 -0
  219. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/helpers/metaculus_api.py +0 -0
  220. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/helpers/prediction_extractor.py +0 -0
  221. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/helpers/structure_output.py +0 -0
  222. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/helpers/works_cited_creator.py +0 -0
  223. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/util/__init__.py +0 -0
  224. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/util/async_batching.py +0 -0
  225. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/util/coda_utils.py +0 -0
  226. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/util/custom_logger.py +0 -0
  227. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/util/file_manipulation.py +0 -0
  228. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/util/jsonable.py +0 -0
  229. {forecasting_tools-0.2.91 → forecasting_tools-0.3.0}/forecasting_tools/util/misc.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forecasting-tools
3
- Version: 0.2.91
3
+ Version: 0.3.0
4
4
  Summary: AI forecasting and research tools to help humans reason about and forecast the future
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -19,31 +19,42 @@ Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3.13
20
20
  Classifier: Programming Language :: Python :: 3.14
21
21
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Provides-Extra: agents
23
+ Provides-Extra: all
24
+ Provides-Extra: front-end
25
+ Provides-Extra: source-archive
26
+ Provides-Extra: stats
22
27
  Requires-Dist: aiofiles (>=24.1.0,<26.0.0)
23
28
  Requires-Dist: aiohttp (>=3.9.3,<4.0.0)
24
29
  Requires-Dist: aiolimiter (>=1.1.0,<2.0.0)
25
- Requires-Dist: asknews (>=0.9.1,<0.14.0)
30
+ Requires-Dist: asknews (>=0.9.1,<0.15.0)
26
31
  Requires-Dist: asyncio (>=3.0.0,<5.0.0)
32
+ Requires-Dist: boto3 (>=1.34,<2.0.0) ; extra == "source-archive" or extra == "all"
33
+ Requires-Dist: cloakbrowser (>=0.3.31,<0.4.0) ; extra == "source-archive" or extra == "all"
27
34
  Requires-Dist: exceptiongroup (>=1.2.2,<2.0.0)
28
- Requires-Dist: faker (>=37.0.0,<41.0.0)
29
- Requires-Dist: hyperbrowser (>=0.53.0,<1.0.0)
35
+ Requires-Dist: faker (>=37.0.0,<41.0.0) ; extra == "agents" or extra == "front-end" or extra == "all"
36
+ Requires-Dist: firecrawl-py (>=4.0,<5.0.0) ; extra == "source-archive" or extra == "all"
37
+ Requires-Dist: hyperbrowser (>=0.53.0,<2.0.0) ; extra == "source-archive" or extra == "agents" or extra == "front-end" or extra == "all"
30
38
  Requires-Dist: litellm (>=1.59.1,<2.0.0,!=1.76.*,!=1.77.*,!=1.82.7,!=1.82.8)
31
39
  Requires-Dist: nest-asyncio (>=1.5.8,<2.0.0)
32
40
  Requires-Dist: numpy (>=1.26.0,<3.0.0)
33
- Requires-Dist: openai (>=1.51.0,<3.0.0)
34
- Requires-Dist: openai-agents[litellm] (>=0.2.0,<0.20.0)
35
- Requires-Dist: pandas (>=2.2.3,<4.0.0)
41
+ Requires-Dist: openai (>=1.51.0,<4.0.0)
42
+ Requires-Dist: openai-agents[litellm] (>=0.2.0,<0.23.0) ; extra == "agents" or extra == "front-end" or extra == "all"
43
+ Requires-Dist: pandas (>=2.2.3,<4.0.0) ; extra == "front-end" or extra == "stats" or extra == "all"
36
44
  Requires-Dist: pendulum (>=3.1.0,<4.0.0)
37
45
  Requires-Dist: pillow (>=9.0.0,<13.0.0)
38
- Requires-Dist: plotly (>=5.24.1,<7.0.0)
46
+ Requires-Dist: playwright (>=1.44,<2.0.0) ; extra == "source-archive" or extra == "all"
47
+ Requires-Dist: plotly (>=5.24.1,<8.0.0) ; extra == "front-end" or extra == "all"
39
48
  Requires-Dist: pydantic (>=2.9.2,<3.0.0)
49
+ Requires-Dist: pymupdf4llm (>=0.0.17,<1.0.0) ; extra == "source-archive" or extra == "all"
40
50
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
41
- Requires-Dist: regex (>=2024.11.6,<2027.0.0)
42
51
  Requires-Dist: requests (>=2.32.3,<3.0.0)
43
- Requires-Dist: scikit-learn (>=1.5.2,<2.0.0)
44
- Requires-Dist: streamlit (>=1.20.0,<2.0.0)
52
+ Requires-Dist: scikit-learn (>=1.5.2,<2.0.0) ; extra == "stats" or extra == "all"
53
+ Requires-Dist: scipy (>=1.10.0,<2.0.0) ; extra == "front-end" or extra == "stats" or extra == "all"
54
+ Requires-Dist: streamlit (>=1.20.0,<2.0.0) ; extra == "front-end" or extra == "all"
45
55
  Requires-Dist: tenacity (>=8.0.0,<10.0.0)
46
56
  Requires-Dist: tiktoken (>=0.8.0,<0.20.0)
57
+ Requires-Dist: trafilatura (>=1.9,<3.0.0) ; extra == "source-archive" or extra == "all"
47
58
  Requires-Dist: typeguard (>=4.3.0,<5.0.0)
48
59
  Requires-Dist: unidecode (>=1.4.0,<2.0.0)
49
60
  Project-URL: Repository, https://github.com/Metaculus/forecasting-tools
@@ -209,7 +220,6 @@ from forecasting_tools import (
209
220
  ReasonedPrediction,
210
221
  PredictedOptionList,
211
222
  NumericDistribution,
212
- SmartSearcher,
213
223
  MetaculusClient,
214
224
  GeneralLlm,
215
225
  PredictionExtractor,
@@ -219,18 +229,13 @@ from forecasting_tools.util.misc import clean_indents
219
229
  class MyCustomBot(TemplateBot):
220
230
 
221
231
  async def run_research(self, question: MetaculusQuestion) -> str:
222
- searcher = SmartSearcher(
223
- num_searches_to_run=2,
224
- num_sites_per_search=10
225
- )
232
+ searcher = GeneralLlm(model="perplexity/sonar-pro", temperature=0)
226
233
 
227
234
  prompt = clean_indents(
228
235
  f"""
229
236
  Analyze this forecasting question:
230
- 1. Filter for recent events in the past 6 months
231
- 2. Don't include domains from youtube.com
232
- 3. Look for current trends and data
233
- 4. Find historical analogies and base rates
237
+ 1. Look for current trends and data
238
+ 2. Find historical analogies and base rates
234
239
 
235
240
  Question: {question.question_text}
236
241
 
@@ -562,6 +567,25 @@ with MonetaryCostManager(max_cost) as cost_manager:
562
567
  print(f"Current cost: ${current_cost:.2f}")
563
568
  ```
564
569
 
570
+ # Optional extras
571
+ Some features need heavier dependencies that a bot does not, so they are opt-in. The base install stays small, and nothing in the template bot or the bot running infrastructure depends on them.
572
+
573
+ | Extra | You need it for |
574
+ | --- | --- |
575
+ | `agents` | Anything built on the agent SDK: `QuestionDecomposer`, `QuestionOperationalizer`, `TopicGenerator`, `DataAnalyzer`, `Benchmarker`, `BenchmarkForBot`, `BotOptimizer`, `CustomizableBot`, `ComputerUse` (browser-driving agent), and the AI Congress tools |
576
+ | `front-end` | The Streamlit app in `forecasting_tools/front_end/` and `run_benchmark_streamlit_page` |
577
+ | `stats` | `forecasting_tools.util.stats` and the calibration adjusters in `forecasting_tools/calibration_adjustment/` |
578
+ | `all` | Everything above |
579
+
580
+ ```bash
581
+ pip install 'forecasting-tools[agents]'
582
+ pip install 'forecasting-tools[agents,front-end]'
583
+ pip install 'forecasting-tools[all]'
584
+ ```
585
+
586
+ If you use one of these features without its extra installed, you get an error telling you exactly which command to run. Importing `forecasting_tools` itself never requires an extra — the affected names are loaded on first access.
587
+
588
+
565
589
  # Local Development
566
590
 
567
591
  ## Environment Variables
@@ -599,8 +623,17 @@ There are many ways to manager Docker containers, but generally if you download
599
623
  If you choose not to run Docker, you can use poetry to set up a local virtual environment. If you are on Ubuntu, you should be able to just read through and then run `.devcontainer/postinstall.sh`. If you aren't on Ubuntu, check out the links in the postinstall file for where install instructions for dependencies were originally found. You may also want to take a look at VSCode extensions that would be installed (see the list in the `.devcontainer/devcontainer.json` file) so that some VSCode workplace settings work out of the box (e.g. automatic Black Formatting).
600
624
 
601
625
 
626
+ ## Installing dependencies
627
+ Local development uses the optional extras (the tests cover the front end, the agent tools, and benchmarking), so install with:
628
+
629
+ ```bash
630
+ poetry install --all-extras
631
+ ```
632
+
633
+ A plain `poetry install` gives you only the base dependencies. That is what the bot-running GitHub workflows use, which keeps them honest about the template bot not needing the extras — but it is not enough to run the full unit test suite.
634
+
602
635
  ## Running the Front End
603
- You can run any front end folder in the front_end directory by executing `streamlit run front_end/main.py`. This will start a development server for you that you can run. Streamlit makes it very easy to publish demos.
636
+ You can run any front end folder in the front_end directory by executing `streamlit run front_end/Home.py`. This will start a development server for you that you can run. Streamlit makes it very easy to publish demos. This needs the `front-end` extra (included in `poetry install --all-extras`).
604
637
 
605
638
  ## Testing
606
639
  This repository uses pytest tests are subdivided into folders 'unit_tests', 'integration'. Unit tests should always pass. You can run `pytest code_tests/unit_tests` or just `pytest` to run all of these
@@ -158,7 +158,6 @@ from forecasting_tools import (
158
158
  ReasonedPrediction,
159
159
  PredictedOptionList,
160
160
  NumericDistribution,
161
- SmartSearcher,
162
161
  MetaculusClient,
163
162
  GeneralLlm,
164
163
  PredictionExtractor,
@@ -168,18 +167,13 @@ from forecasting_tools.util.misc import clean_indents
168
167
  class MyCustomBot(TemplateBot):
169
168
 
170
169
  async def run_research(self, question: MetaculusQuestion) -> str:
171
- searcher = SmartSearcher(
172
- num_searches_to_run=2,
173
- num_sites_per_search=10
174
- )
170
+ searcher = GeneralLlm(model="perplexity/sonar-pro", temperature=0)
175
171
 
176
172
  prompt = clean_indents(
177
173
  f"""
178
174
  Analyze this forecasting question:
179
- 1. Filter for recent events in the past 6 months
180
- 2. Don't include domains from youtube.com
181
- 3. Look for current trends and data
182
- 4. Find historical analogies and base rates
175
+ 1. Look for current trends and data
176
+ 2. Find historical analogies and base rates
183
177
 
184
178
  Question: {question.question_text}
185
179
 
@@ -511,6 +505,25 @@ with MonetaryCostManager(max_cost) as cost_manager:
511
505
  print(f"Current cost: ${current_cost:.2f}")
512
506
  ```
513
507
 
508
+ # Optional extras
509
+ Some features need heavier dependencies that a bot does not, so they are opt-in. The base install stays small, and nothing in the template bot or the bot running infrastructure depends on them.
510
+
511
+ | Extra | You need it for |
512
+ | --- | --- |
513
+ | `agents` | Anything built on the agent SDK: `QuestionDecomposer`, `QuestionOperationalizer`, `TopicGenerator`, `DataAnalyzer`, `Benchmarker`, `BenchmarkForBot`, `BotOptimizer`, `CustomizableBot`, `ComputerUse` (browser-driving agent), and the AI Congress tools |
514
+ | `front-end` | The Streamlit app in `forecasting_tools/front_end/` and `run_benchmark_streamlit_page` |
515
+ | `stats` | `forecasting_tools.util.stats` and the calibration adjusters in `forecasting_tools/calibration_adjustment/` |
516
+ | `all` | Everything above |
517
+
518
+ ```bash
519
+ pip install 'forecasting-tools[agents]'
520
+ pip install 'forecasting-tools[agents,front-end]'
521
+ pip install 'forecasting-tools[all]'
522
+ ```
523
+
524
+ If you use one of these features without its extra installed, you get an error telling you exactly which command to run. Importing `forecasting_tools` itself never requires an extra — the affected names are loaded on first access.
525
+
526
+
514
527
  # Local Development
515
528
 
516
529
  ## Environment Variables
@@ -548,8 +561,17 @@ There are many ways to manager Docker containers, but generally if you download
548
561
  If you choose not to run Docker, you can use poetry to set up a local virtual environment. If you are on Ubuntu, you should be able to just read through and then run `.devcontainer/postinstall.sh`. If you aren't on Ubuntu, check out the links in the postinstall file for where install instructions for dependencies were originally found. You may also want to take a look at VSCode extensions that would be installed (see the list in the `.devcontainer/devcontainer.json` file) so that some VSCode workplace settings work out of the box (e.g. automatic Black Formatting).
549
562
 
550
563
 
564
+ ## Installing dependencies
565
+ Local development uses the optional extras (the tests cover the front end, the agent tools, and benchmarking), so install with:
566
+
567
+ ```bash
568
+ poetry install --all-extras
569
+ ```
570
+
571
+ A plain `poetry install` gives you only the base dependencies. That is what the bot-running GitHub workflows use, which keeps them honest about the template bot not needing the extras — but it is not enough to run the full unit test suite.
572
+
551
573
  ## Running the Front End
552
- You can run any front end folder in the front_end directory by executing `streamlit run front_end/main.py`. This will start a development server for you that you can run. Streamlit makes it very easy to publish demos.
574
+ You can run any front end folder in the front_end directory by executing `streamlit run front_end/Home.py`. This will start a development server for you that you can run. Streamlit makes it very easy to publish demos. This needs the `front-end` extra (included in `poetry install --all-extras`).
553
575
 
554
576
  ## Testing
555
577
  This repository uses pytest tests are subdivided into folders 'unit_tests', 'integration'. Unit tests should always pass. You can run `pytest code_tests/unit_tests` or just `pytest` to run all of these
@@ -1,3 +1,7 @@
1
+ import importlib.util
2
+ import types
3
+ from typing import TYPE_CHECKING, Any
4
+
1
5
  import nest_asyncio
2
6
 
3
7
  from forecasting_tools.agents_and_tools.base_rates.base_rate_researcher import (
@@ -15,21 +19,6 @@ from forecasting_tools.agents_and_tools.base_rates.niche_list_researcher import
15
19
  from forecasting_tools.agents_and_tools.deprecated.question_generator import (
16
20
  QuestionGenerator as QuestionGenerator,
17
21
  )
18
- from forecasting_tools.agents_and_tools.other.data_analyzer import (
19
- DataAnalyzer as DataAnalyzer,
20
- )
21
- from forecasting_tools.agents_and_tools.question_generators.question_decomposer import (
22
- QuestionDecomposer as QuestionDecomposer,
23
- )
24
- from forecasting_tools.agents_and_tools.question_generators.question_operationalizer import (
25
- QuestionOperationalizer as QuestionOperationalizer,
26
- )
27
- from forecasting_tools.agents_and_tools.question_generators.topic_generator import (
28
- TopicGenerator as TopicGenerator,
29
- )
30
- from forecasting_tools.agents_and_tools.research.computer_use import (
31
- ComputerUse as ComputerUse,
32
- )
33
22
  from forecasting_tools.agents_and_tools.research.key_factors_researcher import (
34
23
  KeyFactorsResearcher as KeyFactorsResearcher,
35
24
  )
@@ -66,14 +55,6 @@ from forecasting_tools.ai_models.resource_managers.monetary_cost_manager import
66
55
  from forecasting_tools.ai_models.resource_managers.refreshing_bucket_rate_limiter import (
67
56
  RefreshingBucketRateLimiter as RefreshingBucketRateLimiter,
68
57
  )
69
- from forecasting_tools.auto_optimizers.bot_optimizer import BotOptimizer as BotOptimizer
70
- from forecasting_tools.cp_benchmarking.benchmark_displayer import (
71
- run_benchmark_streamlit_page as run_benchmark_streamlit_page,
72
- )
73
- from forecasting_tools.cp_benchmarking.benchmark_for_bot import (
74
- BenchmarkForBot as BenchmarkForBot,
75
- )
76
- from forecasting_tools.cp_benchmarking.benchmarker import Benchmarker as Benchmarker
77
58
  from forecasting_tools.data_models.binary_report import (
78
59
  BinaryPrediction as BinaryPrediction,
79
60
  )
@@ -196,4 +177,85 @@ from forecasting_tools.helpers.structure_output import (
196
177
  )
197
178
  from forecasting_tools.util.misc import clean_indents as clean_indents
198
179
 
180
+ # Loaded on first access rather than at import time. These names need optional
181
+ # dependencies (see the extras in pyproject.toml), so importing them eagerly
182
+ # would make `import forecasting_tools` fail for anyone who installed only the
183
+ # base package to run a bot.
184
+ _LAZY_EXPORTS: dict[str, str] = {
185
+ "Benchmarker": "forecasting_tools.cp_benchmarking.benchmarker",
186
+ "BenchmarkForBot": "forecasting_tools.cp_benchmarking.benchmark_for_bot",
187
+ "BotOptimizer": "forecasting_tools.auto_optimizers.bot_optimizer",
188
+ "ComputerUse": "forecasting_tools.agents_and_tools.research.computer_use",
189
+ "DataAnalyzer": "forecasting_tools.agents_and_tools.other.data_analyzer",
190
+ "QuestionDecomposer": "forecasting_tools.agents_and_tools.question_generators.question_decomposer",
191
+ "QuestionOperationalizer": "forecasting_tools.agents_and_tools.question_generators.question_operationalizer",
192
+ "TopicGenerator": "forecasting_tools.agents_and_tools.question_generators.topic_generator",
193
+ "run_benchmark_streamlit_page": "forecasting_tools.cp_benchmarking.benchmark_displayer",
194
+ }
195
+
196
+ if TYPE_CHECKING:
197
+ from forecasting_tools.agents_and_tools.other.data_analyzer import (
198
+ DataAnalyzer as DataAnalyzer,
199
+ )
200
+ from forecasting_tools.agents_and_tools.question_generators.question_decomposer import (
201
+ QuestionDecomposer as QuestionDecomposer,
202
+ )
203
+ from forecasting_tools.agents_and_tools.question_generators.question_operationalizer import (
204
+ QuestionOperationalizer as QuestionOperationalizer,
205
+ )
206
+ from forecasting_tools.agents_and_tools.question_generators.topic_generator import (
207
+ TopicGenerator as TopicGenerator,
208
+ )
209
+ from forecasting_tools.agents_and_tools.research.computer_use import (
210
+ ComputerUse as ComputerUse,
211
+ )
212
+ from forecasting_tools.auto_optimizers.bot_optimizer import (
213
+ BotOptimizer as BotOptimizer,
214
+ )
215
+ from forecasting_tools.cp_benchmarking.benchmark_displayer import (
216
+ run_benchmark_streamlit_page as run_benchmark_streamlit_page,
217
+ )
218
+ from forecasting_tools.cp_benchmarking.benchmark_for_bot import (
219
+ BenchmarkForBot as BenchmarkForBot,
220
+ )
221
+ from forecasting_tools.cp_benchmarking.benchmarker import Benchmarker as Benchmarker
222
+
223
+
224
+ def __getattr__(name: str) -> Any:
225
+ module_path = _LAZY_EXPORTS.get(name)
226
+ if module_path is None:
227
+ # Subpackages used to be bound here as a side effect of the eager imports
228
+ # that lived above, so keep `forecasting_tools.<subpackage>` reachable.
229
+ module_path = f"{__name__}.{name}"
230
+ if importlib.util.find_spec(module_path) is None:
231
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
232
+ value = importlib.import_module(module_path)
233
+ else:
234
+ # A missing extra surfaces as ImportError rather than AttributeError so
235
+ # that `from forecasting_tools import Benchmarker` still names the extra
236
+ # to install. Python rewrites an AttributeError raised here into a bare
237
+ # "cannot import name" message, which loses those instructions.
238
+ value = getattr(importlib.import_module(module_path), name)
239
+ globals()[name] = value
240
+ return value
241
+
242
+
243
+ def __dir__() -> list[str]:
244
+ return sorted(set(globals()) | set(_LAZY_EXPORTS))
245
+
246
+
247
+ # Without this, `from forecasting_tools import *` would silently skip the lazy
248
+ # names, since a star import only copies what is already bound in globals().
249
+ _IMPORT_MACHINERY_NAMES = {"TYPE_CHECKING", "Any"}
250
+ __all__ = sorted(
251
+ {
252
+ name
253
+ for name, value in globals().items()
254
+ if not name.startswith("_")
255
+ and name not in _IMPORT_MACHINERY_NAMES
256
+ and not isinstance(value, types.ModuleType)
257
+ }
258
+ | set(_LAZY_EXPORTS)
259
+ )
260
+
199
261
  nest_asyncio.apply()
@@ -32,7 +32,7 @@ LONG_TIMEOUT = 480
32
32
  class CongressOrchestrator:
33
33
  def __init__(
34
34
  self,
35
- aggregation_model: str = "openrouter/anthropic/claude-sonnet-4",
35
+ aggregation_model: str = "openrouter/anthropic/claude-sonnet-4.6",
36
36
  num_delphi_rounds: int = 1,
37
37
  ):
38
38
  self.aggregation_model = aggregation_model
@@ -23,7 +23,7 @@ class CongressMember(BaseModel, Jsonable):
23
23
  general_motivation: str
24
24
  expertise_areas: list[str]
25
25
  personality_traits: list[str]
26
- ai_model: str = "openrouter/anthropic/claude-sonnet-4"
26
+ ai_model: str = "openrouter/anthropic/claude-sonnet-4.6"
27
27
  search_model: str = "openrouter/perplexity/sonar-reasoning-pro"
28
28
 
29
29
  @property
@@ -1,11 +1,15 @@
1
1
  from forecasting_tools.agents_and_tools.ai_congress_v2.data_models import CongressMember
2
2
 
3
+ DEFAULT_POLITICAL_MODEL = "openrouter/anthropic/claude-sonnet-4.6"
4
+
3
5
  # =============================================================================
4
6
  # POLITICAL VALUE-BASED MEMBERS
7
+ # Note: All names below are intentionally fictional and do not refer to any real
8
+ # politician. They are archetypes selected to span a broad ideological space.
5
9
  # =============================================================================
6
10
 
7
11
  TRADITIONAL_CONSERVATIVE = CongressMember(
8
- name="Sen. Burke",
12
+ name="Sen. Thornbury",
9
13
  role="Traditional Conservative",
10
14
  political_leaning="traditional conservative",
11
15
  general_motivation=(
@@ -27,11 +31,11 @@ TRADITIONAL_CONSERVATIVE = CongressMember(
27
31
  "respects established institutions",
28
32
  "emphasizes personal responsibility",
29
33
  ],
30
- ai_model="openrouter/anthropic/claude-sonnet-4.5",
34
+ ai_model=DEFAULT_POLITICAL_MODEL,
31
35
  )
32
36
 
33
37
  PROGRESSIVE_REFORMER = CongressMember(
34
- name="Rep. Warren",
38
+ name="Rep. Hartwell",
35
39
  role="Progressive Reformer",
36
40
  political_leaning="progressive",
37
41
  general_motivation=(
@@ -53,11 +57,11 @@ PROGRESSIVE_REFORMER = CongressMember(
53
57
  "prioritizes workers and consumers",
54
58
  "impatient with incrementalism",
55
59
  ],
56
- ai_model="openrouter/anthropic/claude-sonnet-4.5",
60
+ ai_model=DEFAULT_POLITICAL_MODEL,
57
61
  )
58
62
 
59
63
  LIBERTARIAN = CongressMember(
60
- name="Rep. Paul",
64
+ name="Rep. Calloway",
61
65
  role="Libertarian",
62
66
  political_leaning="libertarian",
63
67
  general_motivation=(
@@ -79,11 +83,11 @@ LIBERTARIAN = CongressMember(
79
83
  "consistent across issues",
80
84
  "opposes paternalism",
81
85
  ],
82
- ai_model="openrouter/anthropic/claude-sonnet-4.5",
86
+ ai_model=DEFAULT_POLITICAL_MODEL,
83
87
  )
84
88
 
85
89
  POPULIST_NATIONALIST = CongressMember(
86
- name="Sen. Vance",
90
+ name="Sen. Marsden",
87
91
  role="Populist Nationalist",
88
92
  political_leaning="populist nationalist",
89
93
  general_motivation=(
@@ -105,11 +109,11 @@ POPULIST_NATIONALIST = CongressMember(
105
109
  "questions free trade orthodoxy",
106
110
  "focuses on forgotten communities",
107
111
  ],
108
- ai_model="openrouter/anthropic/claude-sonnet-4.5",
112
+ ai_model=DEFAULT_POLITICAL_MODEL,
109
113
  )
110
114
 
111
115
  NATIONAL_SECURITY_HAWK = CongressMember(
112
- name="Sen. McCain",
116
+ name="Sen. Ashford",
113
117
  role="National Security Hawk",
114
118
  political_leaning="hawkish internationalist",
115
119
  general_motivation=(
@@ -131,11 +135,11 @@ NATIONAL_SECURITY_HAWK = CongressMember(
131
135
  "willing to use force",
132
136
  "prioritizes deterrence",
133
137
  ],
134
- ai_model="openrouter/anthropic/claude-sonnet-4.5",
138
+ ai_model=DEFAULT_POLITICAL_MODEL,
135
139
  )
136
140
 
137
141
  ENVIRONMENTALIST = CongressMember(
138
- name="Rep. Ocasio",
142
+ name="Rep. Vellacott",
139
143
  role="Climate and Environmental Advocate",
140
144
  political_leaning="green progressive",
141
145
  general_motivation=(
@@ -157,11 +161,11 @@ ENVIRONMENTALIST = CongressMember(
157
161
  "intergenerational focus",
158
162
  "skeptical of fossil fuel industry",
159
163
  ],
160
- ai_model="openrouter/anthropic/claude-sonnet-4.5",
164
+ ai_model=DEFAULT_POLITICAL_MODEL,
161
165
  )
162
166
 
163
167
  DEMOCRATIC_SOCIALIST = CongressMember(
164
- name="Sen. Sanders",
168
+ name="Sen. Quill",
165
169
  role="Democratic Socialist",
166
170
  political_leaning="democratic socialist",
167
171
  general_motivation=(
@@ -183,11 +187,11 @@ DEMOCRATIC_SOCIALIST = CongressMember(
183
187
  "consistent ideology",
184
188
  "grassroots orientation",
185
189
  ],
186
- ai_model="openrouter/anthropic/claude-sonnet-4.5",
190
+ ai_model=DEFAULT_POLITICAL_MODEL,
187
191
  )
188
192
 
189
193
  TECHNOCRATIC_CENTRIST = CongressMember(
190
- name="Sec. Buttigieg",
194
+ name="Sec. Drummond",
191
195
  role="Technocratic Centrist",
192
196
  political_leaning="technocratic centrist",
193
197
  general_motivation=(
@@ -209,7 +213,7 @@ TECHNOCRATIC_CENTRIST = CongressMember(
209
213
  "values expertise",
210
214
  "incrementalist",
211
215
  ],
212
- ai_model="openrouter/anthropic/claude-sonnet-4.5",
216
+ ai_model=DEFAULT_POLITICAL_MODEL,
213
217
  )
214
218
 
215
219
  # =============================================================================
@@ -217,7 +221,7 @@ TECHNOCRATIC_CENTRIST = CongressMember(
217
221
  # =============================================================================
218
222
 
219
223
  CLAUDE_MEMBER = CongressMember(
220
- name="Opus 4.5 (Anthropic)",
224
+ name="Claude Opus 4.7 (Anthropic)",
221
225
  role="AI Policy Analyst",
222
226
  political_leaning="behaves as Claude naturally does",
223
227
  general_motivation=(
@@ -227,7 +231,7 @@ CLAUDE_MEMBER = CongressMember(
227
231
  ),
228
232
  expertise_areas=["general policy analysis"],
229
233
  personality_traits=["behaves naturally as Claude"],
230
- ai_model="openrouter/anthropic/claude-opus-4.5",
234
+ ai_model="openrouter/anthropic/claude-opus-4.7",
231
235
  )
232
236
 
233
237
  GPT_MEMBER = CongressMember(
@@ -245,7 +249,7 @@ GPT_MEMBER = CongressMember(
245
249
  )
246
250
 
247
251
  GEMINI_MEMBER = CongressMember(
248
- name="Gemini 3 Pro (Google)",
252
+ name="Gemini 3.1 Pro (Google)",
249
253
  role="AI Policy Analyst",
250
254
  political_leaning="behaves as Gemini naturally does",
251
255
  general_motivation=(
@@ -255,11 +259,11 @@ GEMINI_MEMBER = CongressMember(
255
259
  ),
256
260
  expertise_areas=["general policy analysis"],
257
261
  personality_traits=["behaves naturally as Gemini"],
258
- ai_model="openrouter/google/gemini-3-pro-preview",
262
+ ai_model="openrouter/google/gemini-3.1-pro-preview",
259
263
  )
260
264
 
261
265
  GROK_MEMBER = CongressMember(
262
- name="Grok 4 (xAI)",
266
+ name="Grok 4.20 (xAI)",
263
267
  role="AI Policy Analyst",
264
268
  political_leaning="behaves as Grok naturally does",
265
269
  general_motivation=(
@@ -269,7 +273,7 @@ GROK_MEMBER = CongressMember(
269
273
  ),
270
274
  expertise_areas=["general policy analysis"],
271
275
  personality_traits=["behaves naturally as Grok"],
272
- ai_model="openrouter/x-ai/grok-4",
276
+ ai_model="openrouter/x-ai/grok-4.20",
273
277
  )
274
278
 
275
279
  DEEPSEEK_MEMBER = CongressMember(
@@ -309,7 +313,7 @@ AI_MODEL_MEMBERS: list[CongressMember] = [
309
313
  DEEPSEEK_MEMBER,
310
314
  ]
311
315
 
312
- AVAILABLE_MEMBERS: list[CongressMember] = POLITICAL_MEMBERS + AI_MODEL_MEMBERS
316
+ AVAILABLE_MEMBERS: list[CongressMember] = AI_MODEL_MEMBERS + POLITICAL_MEMBERS
313
317
 
314
318
  MEMBER_BY_NAME: dict[str, CongressMember] = {m.name: m for m in AVAILABLE_MEMBERS}
315
319
 
@@ -6,7 +6,6 @@ import random
6
6
  import numpy as np
7
7
  import requests
8
8
  from openai import OpenAI
9
- from sklearn.metrics.pairwise import cosine_similarity
10
9
 
11
10
  from forecasting_tools.agents_and_tools.deprecated.configured_llms import BasicLlm
12
11
  from forecasting_tools.agents_and_tools.research.smart_searcher import SmartSearcher
@@ -223,13 +222,22 @@ class Deduplicator:
223
222
  list_embeddings = embeddings[1:]
224
223
 
225
224
  for list_embedding in list_embeddings:
226
- similarity = cosine_similarity(
227
- np.array([text_embedding]), np.array([list_embedding])
228
- )[0][0]
225
+ similarity = cls.__cosine_similarity(text_embedding, list_embedding)
229
226
  if similarity > semantic_similarity_threshold:
230
227
  return True
231
228
  return False
232
229
 
230
+ @staticmethod
231
+ def __cosine_similarity(
232
+ first_vector: list[float], second_vector: list[float]
233
+ ) -> float:
234
+ first = np.asarray(first_vector, dtype=float)
235
+ second = np.asarray(second_vector, dtype=float)
236
+ magnitude = float(np.linalg.norm(first) * np.linalg.norm(second))
237
+ if magnitude == 0.0:
238
+ return 0.0
239
+ return float(np.dot(first, second) / magnitude)
240
+
233
241
  @classmethod
234
242
  def __get_embeddings_using_openai(cls, texts: list[str]) -> list[list[float]]:
235
243
  # TODO: Track costs from this in llm cost tracker
@@ -98,7 +98,7 @@ class DataAnalyzer:
98
98
  def data_analysis_tool(
99
99
  instruction: str,
100
100
  additional_context: str | None = None,
101
- files: list | None = None,
101
+ files: list[AvailableFile] | None = None,
102
102
  ) -> str:
103
103
  """
104
104
  This tool attempts to use code to achieve the user's instructions.
@@ -109,7 +109,7 @@ class DataAnalyzer:
109
109
  Format files as a list of dicts with the following format: {"file_name": "string", "file_id": "string"}
110
110
  """
111
111
  data_analysis = DataAnalyzer()
112
- available_files = [AvailableFile(**file) for file in files] if files else []
112
+ available_files = list(files) if files else []
113
113
  return asyncio.run(
114
114
  data_analysis.run_data_analysis(
115
115
  instruction, additional_context, available_files
@@ -170,10 +170,10 @@ class QuestionDecomposer:
170
170
  related_research: str | None,
171
171
  additional_context: str | None,
172
172
  number_of_questions: int = 5,
173
- model: str | GeneralLlm = GeneralLlm.search_context_model(
174
- "openrouter/perplexity/sonar"
175
- ),
173
+ model: str | GeneralLlm | None = None,
176
174
  ) -> DecompositionResult:
175
+ if model is None:
176
+ model = GeneralLlm.search_context_model("openrouter/perplexity/sonar")
177
177
  llm = GeneralLlm.to_llm(model)
178
178
 
179
179
  prompt = clean_indents(
@@ -11,6 +11,7 @@ from forecasting_tools.ai_models.general_llm import GeneralLlm
11
11
  from forecasting_tools.helpers.asknews_searcher import AskNewsSearcher
12
12
  from forecasting_tools.helpers.structure_output import structure_output
13
13
  from forecasting_tools.util.misc import clean_indents
14
+ from forecasting_tools.util.optional_imports import require_optional_package
14
15
 
15
16
  logger = logging.getLogger(__name__)
16
17
 
@@ -46,6 +47,7 @@ class TopicGenerator:
46
47
  number_of_topics: int = 10,
47
48
  additional_instructions: str = "",
48
49
  ) -> list[str]:
50
+ require_optional_package("faker", "faker", "agents")
49
51
  from faker import Faker
50
52
 
51
53
  if isinstance(model, str):
@@ -216,6 +218,7 @@ class TopicGenerator:
216
218
  model: GeneralLlm | str = "gpt-4o",
217
219
  search_model: GeneralLlm | str = "openrouter/perplexity/sonar-pro",
218
220
  ) -> tuple[OrgInfo, list[str]]:
221
+ require_optional_package("faker", "faker", "agents")
219
222
  from faker import Faker
220
223
 
221
224
  fake = Faker(cls.LANGUAGES)
@@ -2,13 +2,25 @@ import asyncio
2
2
  import logging
3
3
  import os
4
4
 
5
- from hyperbrowser import AsyncHyperbrowser
6
- from hyperbrowser.models import CreateSessionParams, CuaTaskData, StartCuaTaskParams
7
5
  from pydantic import BaseModel
8
6
 
9
- from forecasting_tools.agents_and_tools.other.hosted_file import HostedFile
10
- from forecasting_tools.ai_models.agent_wrappers import agent_tool
11
7
  from forecasting_tools.util.misc import clean_indents
8
+ from forecasting_tools.util.optional_imports import require_optional_package
9
+
10
+ require_optional_package("hyperbrowser", "hyperbrowser", "agents")
11
+ require_optional_package("agents", "openai-agents", "agents")
12
+
13
+ from hyperbrowser import AsyncHyperbrowser # noqa: E402
14
+ from hyperbrowser.models import ( # noqa: E402
15
+ CreateSessionParams,
16
+ CuaTaskData,
17
+ StartCuaTaskParams,
18
+ )
19
+
20
+ from forecasting_tools.agents_and_tools.other.hosted_file import ( # noqa: E402
21
+ HostedFile,
22
+ )
23
+ from forecasting_tools.ai_models.agent_wrappers import agent_tool # noqa: E402
12
24
 
13
25
  logger = logging.getLogger(__name__)
14
26