edsl 0.1.49__tar.gz → 0.1.51__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 (409) hide show
  1. {edsl-0.1.49 → edsl-0.1.51}/PKG-INFO +32 -2
  2. {edsl-0.1.49 → edsl-0.1.51}/README.md +29 -1
  3. edsl-0.1.51/edsl/__init__.py +134 -0
  4. edsl-0.1.51/edsl/__version__.py +1 -0
  5. {edsl-0.1.49 → edsl-0.1.51}/edsl/agents/agent.py +21 -21
  6. {edsl-0.1.49 → edsl-0.1.51}/edsl/agents/agent_list.py +2 -5
  7. edsl-0.1.51/edsl/agents/exceptions.py +159 -0
  8. {edsl-0.1.49 → edsl-0.1.51}/edsl/base/__init__.py +10 -35
  9. {edsl-0.1.49 → edsl-0.1.51}/edsl/base/base_class.py +71 -36
  10. edsl-0.1.51/edsl/base/base_exception.py +204 -0
  11. {edsl-0.1.49 → edsl-0.1.51}/edsl/base/data_transfer_models.py +1 -1
  12. edsl-0.1.51/edsl/base/exceptions.py +94 -0
  13. {edsl-0.1.49 → edsl-0.1.51}/edsl/buckets/__init__.py +15 -1
  14. {edsl-0.1.49 → edsl-0.1.51}/edsl/buckets/bucket_collection.py +3 -4
  15. edsl-0.1.51/edsl/buckets/exceptions.py +107 -0
  16. {edsl-0.1.49 → edsl-0.1.51}/edsl/buckets/model_buckets.py +1 -2
  17. {edsl-0.1.49 → edsl-0.1.51}/edsl/buckets/token_bucket.py +11 -6
  18. {edsl-0.1.49 → edsl-0.1.51}/edsl/buckets/token_bucket_api.py +27 -12
  19. {edsl-0.1.49 → edsl-0.1.51}/edsl/buckets/token_bucket_client.py +9 -7
  20. {edsl-0.1.49 → edsl-0.1.51}/edsl/caching/cache.py +12 -4
  21. {edsl-0.1.49 → edsl-0.1.51}/edsl/caching/cache_entry.py +10 -9
  22. edsl-0.1.51/edsl/caching/exceptions.py +130 -0
  23. {edsl-0.1.49 → edsl-0.1.51}/edsl/caching/remote_cache_sync.py +6 -7
  24. {edsl-0.1.49 → edsl-0.1.51}/edsl/caching/sql_dict.py +20 -14
  25. edsl-0.1.51/edsl/cli.py +43 -0
  26. {edsl-0.1.49 → edsl-0.1.51}/edsl/config/__init__.py +1 -1
  27. {edsl-0.1.49 → edsl-0.1.51}/edsl/config/config_class.py +32 -6
  28. {edsl-0.1.49 → edsl-0.1.51}/edsl/conversation/Conversation.py +8 -4
  29. {edsl-0.1.49 → edsl-0.1.51}/edsl/conversation/car_buying.py +1 -3
  30. edsl-0.1.51/edsl/conversation/exceptions.py +58 -0
  31. {edsl-0.1.49 → edsl-0.1.51}/edsl/conversation/mug_negotiation.py +2 -8
  32. {edsl-0.1.49 → edsl-0.1.51}/edsl/coop/__init__.py +28 -6
  33. {edsl-0.1.49 → edsl-0.1.51}/edsl/coop/coop.py +120 -29
  34. {edsl-0.1.49 → edsl-0.1.51}/edsl/coop/coop_functions.py +1 -1
  35. {edsl-0.1.49 → edsl-0.1.51}/edsl/coop/ep_key_handling.py +1 -1
  36. edsl-0.1.51/edsl/coop/exceptions.py +241 -0
  37. {edsl-0.1.49 → edsl-0.1.51}/edsl/coop/price_fetcher.py +5 -8
  38. {edsl-0.1.49 → edsl-0.1.51}/edsl/coop/utils.py +4 -6
  39. edsl-0.1.51/edsl/dataset/__init__.py +11 -0
  40. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/dataset.py +177 -86
  41. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/dataset_operations_mixin.py +98 -76
  42. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/dataset_tree.py +11 -7
  43. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/display/table_display.py +0 -2
  44. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/display/table_renderers.py +6 -4
  45. edsl-0.1.51/edsl/dataset/exceptions.py +125 -0
  46. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/file_exports.py +18 -11
  47. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/r/ggplot.py +13 -6
  48. edsl-0.1.51/edsl/display/__init__.py +27 -0
  49. edsl-0.1.51/edsl/display/core.py +147 -0
  50. edsl-0.1.51/edsl/display/plugin.py +189 -0
  51. edsl-0.1.51/edsl/display/utils.py +52 -0
  52. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/__init__.py +9 -1
  53. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/available_model_cache_handler.py +1 -1
  54. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/available_model_fetcher.py +5 -6
  55. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/data_structures.py +10 -7
  56. edsl-0.1.51/edsl/inference_services/exceptions.py +136 -0
  57. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/inference_service_abc.py +2 -2
  58. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/inference_services_collection.py +2 -6
  59. edsl-0.1.51/edsl/inference_services/registry.py +9 -0
  60. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/service_availability.py +4 -3
  61. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/anthropic_service.py +4 -1
  62. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/aws_bedrock.py +13 -12
  63. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/azure_ai.py +12 -10
  64. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/deep_infra_service.py +1 -4
  65. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/deep_seek_service.py +1 -5
  66. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/google_service.py +7 -3
  67. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/groq_service.py +1 -1
  68. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/mistral_ai_service.py +4 -2
  69. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/ollama_service.py +1 -1
  70. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/open_ai_service.py +7 -5
  71. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/perplexity_service.py +6 -2
  72. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/test_service.py +8 -7
  73. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/together_ai_service.py +2 -3
  74. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/xai_service.py +1 -1
  75. {edsl-0.1.49 → edsl-0.1.51}/edsl/instructions/__init__.py +1 -1
  76. {edsl-0.1.49 → edsl-0.1.51}/edsl/instructions/change_instruction.py +7 -5
  77. edsl-0.1.51/edsl/instructions/exceptions.py +61 -0
  78. {edsl-0.1.49 → edsl-0.1.51}/edsl/instructions/instruction.py +6 -2
  79. {edsl-0.1.49 → edsl-0.1.51}/edsl/instructions/instruction_collection.py +6 -4
  80. {edsl-0.1.49 → edsl-0.1.51}/edsl/instructions/instruction_handler.py +12 -15
  81. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/ReportErrors.py +0 -3
  82. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/__init__.py +9 -2
  83. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/answering_function.py +11 -13
  84. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/exception_tracking.py +15 -8
  85. edsl-0.1.51/edsl/interviews/exceptions.py +79 -0
  86. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/interview.py +33 -30
  87. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/interview_status_dictionary.py +4 -2
  88. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/interview_status_log.py +2 -1
  89. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/interview_task_manager.py +5 -5
  90. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/request_token_estimator.py +5 -2
  91. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/statistics.py +3 -4
  92. {edsl-0.1.49 → edsl-0.1.51}/edsl/invigilators/__init__.py +7 -1
  93. edsl-0.1.51/edsl/invigilators/exceptions.py +79 -0
  94. {edsl-0.1.49 → edsl-0.1.51}/edsl/invigilators/invigilator_base.py +0 -1
  95. {edsl-0.1.49 → edsl-0.1.51}/edsl/invigilators/invigilators.py +9 -13
  96. {edsl-0.1.49 → edsl-0.1.51}/edsl/invigilators/prompt_constructor.py +1 -5
  97. {edsl-0.1.49 → edsl-0.1.51}/edsl/invigilators/prompt_helpers.py +8 -4
  98. {edsl-0.1.49 → edsl-0.1.51}/edsl/invigilators/question_instructions_prompt_builder.py +1 -1
  99. {edsl-0.1.49 → edsl-0.1.51}/edsl/invigilators/question_option_processor.py +9 -5
  100. {edsl-0.1.49 → edsl-0.1.51}/edsl/invigilators/question_template_replacements_builder.py +3 -2
  101. edsl-0.1.51/edsl/jobs/__init__.py +44 -0
  102. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/async_interview_runner.py +25 -23
  103. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/check_survey_scenario_compatibility.py +11 -10
  104. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/data_structures.py +8 -5
  105. edsl-0.1.51/edsl/jobs/exceptions.py +195 -0
  106. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/fetch_invigilator.py +1 -1
  107. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/jobs.py +74 -69
  108. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/jobs_checks.py +6 -7
  109. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/jobs_component_constructor.py +4 -4
  110. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/jobs_pricing_estimation.py +4 -3
  111. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/jobs_remote_inference_logger.py +5 -4
  112. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/jobs_runner_asyncio.py +3 -4
  113. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/jobs_runner_status.py +8 -9
  114. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/remote_inference.py +27 -24
  115. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/results_exceptions_handler.py +10 -7
  116. {edsl-0.1.49 → edsl-0.1.51}/edsl/key_management/__init__.py +3 -1
  117. edsl-0.1.51/edsl/key_management/exceptions.py +62 -0
  118. {edsl-0.1.49 → edsl-0.1.51}/edsl/key_management/key_lookup.py +1 -1
  119. {edsl-0.1.49 → edsl-0.1.51}/edsl/key_management/key_lookup_builder.py +37 -14
  120. {edsl-0.1.49 → edsl-0.1.51}/edsl/key_management/key_lookup_collection.py +2 -0
  121. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/__init__.py +1 -1
  122. edsl-0.1.51/edsl/language_models/exceptions.py +356 -0
  123. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/language_model.py +9 -8
  124. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/model.py +4 -4
  125. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/model_list.py +1 -1
  126. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/price_manager.py +1 -1
  127. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/raw_response_handler.py +14 -9
  128. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/registry.py +17 -21
  129. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/repair.py +0 -6
  130. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/unused/fake_openai_service.py +0 -1
  131. edsl-0.1.51/edsl/load_plugins.py +69 -0
  132. edsl-0.1.51/edsl/logger.py +146 -0
  133. edsl-0.1.51/edsl/notebooks/__init__.py +26 -0
  134. edsl-0.1.51/edsl/notebooks/exceptions.py +82 -0
  135. {edsl-0.1.49 → edsl-0.1.51}/edsl/notebooks/notebook.py +7 -3
  136. {edsl-0.1.49 → edsl-0.1.51}/edsl/notebooks/notebook_to_latex.py +1 -2
  137. edsl-0.1.51/edsl/plugins/__init__.py +63 -0
  138. edsl-0.1.51/edsl/plugins/built_in/export_example.py +50 -0
  139. edsl-0.1.51/edsl/plugins/built_in/pig_latin.py +67 -0
  140. edsl-0.1.51/edsl/plugins/cli.py +372 -0
  141. edsl-0.1.51/edsl/plugins/cli_typer.py +283 -0
  142. edsl-0.1.51/edsl/plugins/exceptions.py +31 -0
  143. edsl-0.1.51/edsl/plugins/hookspec.py +51 -0
  144. edsl-0.1.51/edsl/plugins/plugin_host.py +128 -0
  145. edsl-0.1.51/edsl/plugins/plugin_manager.py +633 -0
  146. edsl-0.1.51/edsl/plugins/plugins_registry.py +168 -0
  147. edsl-0.1.51/edsl/prompts/__init__.py +25 -0
  148. edsl-0.1.51/edsl/prompts/exceptions.py +119 -0
  149. {edsl-0.1.49 → edsl-0.1.51}/edsl/prompts/prompt.py +15 -7
  150. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/HTMLQuestion.py +5 -11
  151. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/Quick.py +0 -1
  152. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/__init__.py +6 -4
  153. edsl-0.1.51/edsl/questions/answer_validator_mixin.py +358 -0
  154. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/compose_questions.py +3 -3
  155. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/descriptors.py +11 -50
  156. edsl-0.1.51/edsl/questions/exceptions.py +362 -0
  157. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/loop_processor.py +7 -5
  158. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/prompt_templates/question_list.jinja +3 -0
  159. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/question_base.py +46 -19
  160. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/question_base_gen_mixin.py +2 -2
  161. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/question_base_prompts_mixin.py +13 -7
  162. edsl-0.1.51/edsl/questions/question_budget.py +631 -0
  163. edsl-0.1.51/edsl/questions/question_check_box.py +859 -0
  164. edsl-0.1.51/edsl/questions/question_dict.py +528 -0
  165. edsl-0.1.51/edsl/questions/question_extract.py +520 -0
  166. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/question_free_text.py +80 -14
  167. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/question_functional.py +119 -9
  168. {edsl-0.1.49/edsl/questions/derived → edsl-0.1.51/edsl/questions}/question_likert_five.py +2 -2
  169. {edsl-0.1.49/edsl/questions/derived → edsl-0.1.51/edsl/questions}/question_linear_scale.py +3 -4
  170. edsl-0.1.51/edsl/questions/question_list.py +469 -0
  171. edsl-0.1.51/edsl/questions/question_matrix.py +813 -0
  172. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/question_multiple_choice.py +219 -51
  173. edsl-0.1.51/edsl/questions/question_numerical.py +480 -0
  174. edsl-0.1.51/edsl/questions/question_rank.py +591 -0
  175. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/question_registry.py +7 -5
  176. {edsl-0.1.49/edsl/questions/derived → edsl-0.1.51/edsl/questions}/question_top_k.py +3 -3
  177. {edsl-0.1.49/edsl/questions/derived → edsl-0.1.51/edsl/questions}/question_yes_no.py +3 -4
  178. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/register_questions_meta.py +2 -2
  179. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/response_validator_abc.py +13 -15
  180. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/response_validator_factory.py +10 -12
  181. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/dict/answering_instructions.jinja +1 -0
  182. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/rank/question_presentation.jinja +1 -1
  183. {edsl-0.1.49 → edsl-0.1.51}/edsl/results/__init__.py +1 -1
  184. edsl-0.1.51/edsl/results/exceptions.py +163 -0
  185. {edsl-0.1.49 → edsl-0.1.51}/edsl/results/report.py +1 -2
  186. {edsl-0.1.49 → edsl-0.1.51}/edsl/results/result.py +11 -9
  187. {edsl-0.1.49 → edsl-0.1.51}/edsl/results/results.py +480 -321
  188. {edsl-0.1.49 → edsl-0.1.51}/edsl/results/results_selector.py +8 -4
  189. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/PdfExtractor.py +2 -2
  190. edsl-0.1.51/edsl/scenarios/construct_download_link.py +150 -0
  191. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/directory_scanner.py +33 -14
  192. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/document_chunker.py +1 -1
  193. edsl-0.1.51/edsl/scenarios/exceptions.py +325 -0
  194. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/file_methods.py +1 -1
  195. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/file_store.py +7 -3
  196. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/__init__.py +17 -0
  197. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/docx_file_store.py +0 -5
  198. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/pdf_file_store.py +0 -1
  199. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/pptx_file_store.py +0 -5
  200. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/py_file_store.py +0 -1
  201. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/sql_file_store.py +1 -4
  202. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/sqlite_file_store.py +0 -1
  203. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/txt_file_store.py +1 -1
  204. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/scenario.py +1 -3
  205. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/scenario_list.py +179 -27
  206. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/scenario_list_pdf_tools.py +1 -0
  207. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/scenario_selector.py +0 -1
  208. edsl-0.1.51/edsl/surveys/__init__.py +7 -0
  209. edsl-0.1.51/edsl/surveys/dag/__init__.py +4 -0
  210. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/descriptors.py +1 -1
  211. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/edit_survey.py +1 -0
  212. edsl-0.1.51/edsl/surveys/exceptions.py +192 -0
  213. edsl-0.1.51/edsl/surveys/memory/__init__.py +5 -0
  214. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/memory/memory_management.py +1 -0
  215. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/memory/memory_plan.py +6 -15
  216. edsl-0.1.51/edsl/surveys/rules/__init__.py +5 -0
  217. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/rules/rule.py +1 -2
  218. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/rules/rule_collection.py +1 -1
  219. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/survey.py +12 -24
  220. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/survey_css.py +3 -3
  221. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/survey_export.py +6 -3
  222. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/survey_flow_visualization.py +10 -1
  223. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/survey_simulator.py +2 -1
  224. {edsl-0.1.49 → edsl-0.1.51}/edsl/tasks/__init__.py +23 -1
  225. edsl-0.1.51/edsl/tasks/exceptions.py +72 -0
  226. {edsl-0.1.49 → edsl-0.1.51}/edsl/tasks/question_task_creator.py +3 -3
  227. {edsl-0.1.49 → edsl-0.1.51}/edsl/tasks/task_creators.py +1 -3
  228. {edsl-0.1.49 → edsl-0.1.51}/edsl/tasks/task_history.py +8 -10
  229. {edsl-0.1.49 → edsl-0.1.51}/edsl/tasks/task_status_log.py +1 -2
  230. edsl-0.1.51/edsl/tokens/__init__.py +30 -0
  231. edsl-0.1.51/edsl/tokens/exceptions.py +37 -0
  232. {edsl-0.1.49 → edsl-0.1.51}/edsl/tokens/interview_token_usage.py +3 -2
  233. {edsl-0.1.49 → edsl-0.1.51}/edsl/tokens/token_usage.py +4 -3
  234. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/__init__.py +21 -1
  235. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/decorators.py +1 -2
  236. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/markdown_to_docx.py +2 -2
  237. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/markdown_to_pdf.py +1 -1
  238. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/repair_functions.py +0 -1
  239. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/restricted_python.py +0 -1
  240. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/template_loader.py +2 -3
  241. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/utilities.py +8 -29
  242. {edsl-0.1.49 → edsl-0.1.51}/pyproject.toml +9 -1
  243. edsl-0.1.49/edsl/__init__.py +0 -63
  244. edsl-0.1.49/edsl/__version__.py +0 -1
  245. edsl-0.1.49/edsl/agents/exceptions.py +0 -45
  246. edsl-0.1.49/edsl/caching/exceptions.py +0 -24
  247. edsl-0.1.49/edsl/coop/exceptions.py +0 -62
  248. edsl-0.1.49/edsl/dataset/__init__.py +0 -10
  249. edsl-0.1.49/edsl/dataset/smart_objects.py +0 -96
  250. edsl-0.1.49/edsl/exceptions/BaseException.py +0 -21
  251. edsl-0.1.49/edsl/exceptions/__init__.py +0 -54
  252. edsl-0.1.49/edsl/exceptions/configuration.py +0 -16
  253. edsl-0.1.49/edsl/exceptions/general.py +0 -34
  254. edsl-0.1.49/edsl/inference_services/exceptions.py +0 -5
  255. edsl-0.1.49/edsl/inference_services/registry.py +0 -8
  256. edsl-0.1.49/edsl/jobs/__init__.py +0 -7
  257. edsl-0.1.49/edsl/jobs/exceptions.py +0 -26
  258. edsl-0.1.49/edsl/language_models/exceptions.py +0 -68
  259. edsl-0.1.49/edsl/notebooks/__init__.py +0 -3
  260. edsl-0.1.49/edsl/prompts/__init__.py +0 -2
  261. edsl-0.1.49/edsl/prompts/exceptions.py +0 -17
  262. edsl-0.1.49/edsl/questions/answer_validator_mixin.py +0 -363
  263. edsl-0.1.49/edsl/questions/exceptions.py +0 -106
  264. edsl-0.1.49/edsl/questions/question_budget.py +0 -226
  265. edsl-0.1.49/edsl/questions/question_check_box.py +0 -359
  266. edsl-0.1.49/edsl/questions/question_dict.py +0 -377
  267. edsl-0.1.49/edsl/questions/question_extract.py +0 -180
  268. edsl-0.1.49/edsl/questions/question_list.py +0 -222
  269. edsl-0.1.49/edsl/questions/question_matrix.py +0 -266
  270. edsl-0.1.49/edsl/questions/question_numerical.py +0 -151
  271. edsl-0.1.49/edsl/questions/question_rank.py +0 -314
  272. edsl-0.1.49/edsl/questions/templates/yes_no/__init__.py +0 -0
  273. edsl-0.1.49/edsl/results/exceptions.py +0 -29
  274. edsl-0.1.49/edsl/scenarios/construct_download_link.py +0 -116
  275. edsl-0.1.49/edsl/scenarios/exceptions.py +0 -101
  276. edsl-0.1.49/edsl/study/ObjectEntry.py +0 -173
  277. edsl-0.1.49/edsl/study/ProofOfWork.py +0 -113
  278. edsl-0.1.49/edsl/study/SnapShot.py +0 -80
  279. edsl-0.1.49/edsl/study/Study.py +0 -520
  280. edsl-0.1.49/edsl/study/__init__.py +0 -6
  281. edsl-0.1.49/edsl/surveys/__init__.py +0 -8
  282. edsl-0.1.49/edsl/surveys/dag/__init__.py +0 -2
  283. edsl-0.1.49/edsl/surveys/exceptions.py +0 -36
  284. edsl-0.1.49/edsl/surveys/memory/__init__.py +0 -3
  285. edsl-0.1.49/edsl/surveys/rules/__init__.py +0 -3
  286. edsl-0.1.49/edsl/tokens/__init__.py +0 -2
  287. edsl-0.1.49/edsl/utilities/interface.py +0 -135
  288. {edsl-0.1.49 → edsl-0.1.51}/LICENSE +0 -0
  289. {edsl-0.1.49 → edsl-0.1.51}/edsl/agents/__init__.py +0 -0
  290. {edsl-0.1.49 → edsl-0.1.51}/edsl/agents/descriptors.py +0 -0
  291. {edsl-0.1.49 → edsl-0.1.51}/edsl/base/enums.py +0 -0
  292. {edsl-0.1.49 → edsl-0.1.51}/edsl/base.py +0 -0
  293. {edsl-0.1.49 → edsl-0.1.51}/edsl/caching/__init__.py +0 -0
  294. {edsl-0.1.49 → edsl-0.1.51}/edsl/caching/cache_handler.py +0 -0
  295. {edsl-0.1.49 → edsl-0.1.51}/edsl/caching/orm.py +0 -0
  296. {edsl-0.1.49 → edsl-0.1.51}/edsl/config.py +0 -0
  297. {edsl-0.1.49 → edsl-0.1.51}/edsl/conversation/chips.py +0 -0
  298. {edsl-0.1.49 → edsl-0.1.51}/edsl/conversation/next_speaker_utilities.py +0 -0
  299. {edsl-0.1.49 → edsl-0.1.51}/edsl/data_transfer_models.py +0 -0
  300. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/display/CSSParameterizer.py +0 -0
  301. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/display/__init__.py +0 -0
  302. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/display/table_data_class.py +0 -0
  303. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/display/table_display.css +0 -0
  304. {edsl-0.1.49 → edsl-0.1.51}/edsl/dataset/tree_explore.py +0 -0
  305. {edsl-0.1.49 → edsl-0.1.51}/edsl/enums.py +0 -0
  306. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/models_available_cache.py +0 -0
  307. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/rate_limits_cache.py +0 -0
  308. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/services/__init__.py +0 -0
  309. {edsl-0.1.49 → edsl-0.1.51}/edsl/inference_services/write_available.py +0 -0
  310. {edsl-0.1.49 → edsl-0.1.51}/edsl/interviews/interview_status_enum.py +0 -0
  311. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/decorators.py +0 -0
  312. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/html_table_job_logger.py +0 -0
  313. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/jobs_interview_constructor.py +0 -0
  314. {edsl-0.1.49 → edsl-0.1.51}/edsl/jobs/jobs_status_enums.py +0 -0
  315. {edsl-0.1.49 → edsl-0.1.51}/edsl/key_management/models.py +0 -0
  316. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/compute_cost.py +0 -0
  317. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/unused/fake_openai_call.py +0 -0
  318. {edsl-0.1.49 → edsl-0.1.51}/edsl/language_models/utilities.py +0 -0
  319. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/ExceptionExplainer.py +0 -0
  320. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/data_structures.py +0 -0
  321. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/decorators.py +0 -0
  322. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/prompt_templates/question_budget.jinja +0 -0
  323. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/prompt_templates/question_checkbox.jinja +0 -0
  324. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/prompt_templates/question_extract.jinja +0 -0
  325. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/prompt_templates/question_free_text.jinja +0 -0
  326. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/prompt_templates/question_linear_scale.jinja +0 -0
  327. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/prompt_templates/question_multiple_choice.jinja +0 -0
  328. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/prompt_templates/question_numerical.jinja +0 -0
  329. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/settings.py +0 -0
  330. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/simple_ask_mixin.py +0 -0
  331. {edsl-0.1.49/edsl/questions/derived → edsl-0.1.51/edsl/questions/templates}/__init__.py +0 -0
  332. {edsl-0.1.49/edsl/questions/templates → edsl-0.1.51/edsl/questions/templates/budget}/__init__.py +0 -0
  333. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/budget/answering_instructions.jinja +0 -0
  334. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/budget/question_presentation.jinja +0 -0
  335. {edsl-0.1.49/edsl/questions/templates/budget → edsl-0.1.51/edsl/questions/templates/checkbox}/__init__.py +0 -0
  336. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/checkbox/answering_instructions.jinja +0 -0
  337. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/checkbox/question_presentation.jinja +0 -0
  338. {edsl-0.1.49/edsl/questions/templates/checkbox → edsl-0.1.51/edsl/questions/templates/dict}/__init__.py +0 -0
  339. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/dict/question_presentation.jinja +0 -0
  340. {edsl-0.1.49/edsl/questions/templates/dict → edsl-0.1.51/edsl/questions/templates/extract}/__init__.py +0 -0
  341. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/extract/answering_instructions.jinja +0 -0
  342. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/extract/question_presentation.jinja +0 -0
  343. {edsl-0.1.49/edsl/questions/templates/extract → edsl-0.1.51/edsl/questions/templates/free_text}/__init__.py +0 -0
  344. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/free_text/answering_instructions.jinja +0 -0
  345. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/free_text/question_presentation.jinja +0 -0
  346. {edsl-0.1.49/edsl/questions/templates/free_text → edsl-0.1.51/edsl/questions/templates/likert_five}/__init__.py +0 -0
  347. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/likert_five/answering_instructions.jinja +0 -0
  348. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/likert_five/question_presentation.jinja +0 -0
  349. {edsl-0.1.49/edsl/questions/templates/likert_five → edsl-0.1.51/edsl/questions/templates/linear_scale}/__init__.py +0 -0
  350. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/linear_scale/answering_instructions.jinja +0 -0
  351. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/linear_scale/question_presentation.jinja +0 -0
  352. {edsl-0.1.49/edsl/questions/templates/linear_scale → edsl-0.1.51/edsl/questions/templates/list}/__init__.py +0 -0
  353. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/list/answering_instructions.jinja +0 -0
  354. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/list/question_presentation.jinja +0 -0
  355. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/matrix/__init__.py +0 -0
  356. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/matrix/answering_instructions.jinja +0 -0
  357. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/matrix/question_presentation.jinja +0 -0
  358. {edsl-0.1.49/edsl/questions/templates/list → edsl-0.1.51/edsl/questions/templates/multiple_choice}/__init__.py +0 -0
  359. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/multiple_choice/answering_instructions.jinja +0 -0
  360. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/multiple_choice/html.jinja +0 -0
  361. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/multiple_choice/question_presentation.jinja +0 -0
  362. {edsl-0.1.49/edsl/questions/templates/multiple_choice → edsl-0.1.51/edsl/questions/templates/numerical}/__init__.py +0 -0
  363. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/numerical/answering_instructions.jinja +0 -0
  364. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/numerical/question_presentation.jinja +0 -0
  365. {edsl-0.1.49/edsl/questions/templates/numerical → edsl-0.1.51/edsl/questions/templates/rank}/__init__.py +0 -0
  366. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/rank/answering_instructions.jinja +0 -0
  367. {edsl-0.1.49/edsl/questions/templates/rank → edsl-0.1.51/edsl/questions/templates/top_k}/__init__.py +0 -0
  368. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/top_k/answering_instructions.jinja +0 -0
  369. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/top_k/question_presentation.jinja +0 -0
  370. {edsl-0.1.49/edsl/questions/templates/top_k → edsl-0.1.51/edsl/questions/templates/yes_no}/__init__.py +0 -0
  371. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/yes_no/answering_instructions.jinja +0 -0
  372. {edsl-0.1.49 → edsl-0.1.51}/edsl/questions/templates/yes_no/question_presentation.jinja +0 -0
  373. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/DocxScenario.py +0 -0
  374. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/__init__.py +0 -0
  375. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/csv_file_store.py +0 -0
  376. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/html_file_store.py +0 -0
  377. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/jpeg_file_store.py +0 -0
  378. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/json_file_store.py +0 -0
  379. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/latex_file_store.py +0 -0
  380. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/md_file_store.py +0 -0
  381. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/handlers/png_file_store.py +0 -0
  382. {edsl-0.1.49 → edsl-0.1.51}/edsl/scenarios/scenario_join.py +0 -0
  383. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/base.py +0 -0
  384. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/dag/construct_dag.py +0 -0
  385. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/dag/dag.py +0 -0
  386. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/memory/memory.py +0 -0
  387. {edsl-0.1.49 → edsl-0.1.51}/edsl/surveys/rules/rule_manager.py +0 -0
  388. {edsl-0.1.49 → edsl-0.1.51}/edsl/tasks/task_status_enum.py +0 -0
  389. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/base.html +0 -0
  390. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/exceptions_by_model.html +0 -0
  391. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/exceptions_by_question_name.html +0 -0
  392. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/exceptions_by_type.html +0 -0
  393. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/exceptions_table.html +0 -0
  394. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/interview_details.html +0 -0
  395. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/interviews.html +0 -0
  396. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/overview.html +0 -0
  397. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/performance_plot.html +0 -0
  398. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/report.css +0 -0
  399. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/report.html +0 -0
  400. {edsl-0.1.49 → edsl-0.1.51}/edsl/templates/error_reporting/report.js +0 -0
  401. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/PrettyList.py +0 -0
  402. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/SystemInfo.py +0 -0
  403. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/ast_utilities.py +0 -0
  404. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/gcp_bucket/__init__.py +0 -0
  405. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/gcp_bucket/cloud_storage.py +0 -0
  406. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/is_notebook.py +0 -0
  407. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/is_valid_variable_name.py +0 -0
  408. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/naming_utilities.py +0 -0
  409. {edsl-0.1.49 → edsl-0.1.51}/edsl/utilities/remove_edsl_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.49
3
+ Version: 0.1.51
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
@@ -36,6 +36,7 @@ Requires-Dist: openai (>=1.4.0,<2.0.0)
36
36
  Requires-Dist: openpyxl (>=3.1.5,<4.0.0)
37
37
  Requires-Dist: pandas (>=2.1.4,<3.0.0)
38
38
  Requires-Dist: platformdirs (>=4.3.6,<5.0.0)
39
+ Requires-Dist: pluggy (>=1.3.0,<2.0.0)
39
40
  Requires-Dist: pydot (>=2.0.0,<3.0.0)
40
41
  Requires-Dist: pygments (>=2.17.2,<3.0.0)
41
42
  Requires-Dist: pypdf2 (>=3.0.1,<4.0.0)
@@ -50,6 +51,7 @@ Requires-Dist: simpleeval (>=0.9.13,<0.10.0)
50
51
  Requires-Dist: sqlalchemy (>=2.0.23,<3.0.0)
51
52
  Requires-Dist: tabulate (>=0.9.0,<0.10.0)
52
53
  Requires-Dist: tenacity (>=8.2.3,<9.0.0)
54
+ Requires-Dist: typer[all] (>=0.9.0,<0.10.0)
53
55
  Requires-Dist: urllib3 (>=1.25.4,<1.27)
54
56
  Project-URL: Documentation, https://docs.expectedparrot.com
55
57
  Description-Content-Type: text/markdown
@@ -198,6 +200,27 @@ results.select("color", "flower")
198
200
  **Caching**:
199
201
  API calls to LLMs are cached automatically, allowing you to retrieve responses to questions that have already been run and reproduce experiments at no cost. Learn more about how the <a href="https://docs.expectedparrot.com/en/latest/remote_caching.html" target="_blank" rel="noopener noreferrer">universal remote cache</a> works.
200
202
 
203
+ **Logging**:
204
+ EDSL includes a comprehensive logging system to help with debugging and monitoring. Control log levels and see important information about operations:
205
+
206
+ ```python
207
+ from edsl import logger
208
+ import logging
209
+
210
+ # Set the logging level
211
+ logger.set_level(logging.DEBUG) # Show all log messages
212
+
213
+ # Get a module-specific logger
214
+ my_logger = logger.get_logger(__name__)
215
+ my_logger.info("This is a module-specific log message")
216
+
217
+ # Log messages at different levels
218
+ logger.debug("Detailed debugging information")
219
+ logger.info("General information about operation")
220
+ logger.warning("Something unexpected but not critical")
221
+ logger.error("Something went wrong")
222
+ ```
223
+
201
224
  **Flexibility**:
202
225
  Choose whether to run surveys on your own computer or at the Expected Parrot server.
203
226
 
@@ -231,6 +254,13 @@ Analyze results as specified datasets from your account or workspace. Easily imp
231
254
  - API keys for language models. You can use your own keys or an Expected Parrot key that provides access to all available models.
232
255
  See instructions on <a href="https://docs.expectedparrot.com/en/latest/api_keys.html" target="_blank" rel="noopener noreferrer">managing keys</a> and <a href="https://www.expectedparrot.com/getting-started/coop-pricing" target="_blank" rel="noopener noreferrer">model pricing and performance</a> information.
233
256
 
257
+ ## Developer Notes
258
+
259
+ ### Running Tests
260
+ - Unit tests: `python -m pytest tests/`
261
+ - Integration tests: `python -m pytest integration/`
262
+ - Doctests: `python run_doctests.py` (use `-v` flag for verbose output)
263
+
234
264
  ## Coop
235
265
  An integrated platform for running experiments, sharing workflows and launching hybrid human/AI surveys.
236
266
  - <a href="https://www.expectedparrot.com/login" target="_blank" rel="noopener noreferrer">Login / Signup</a>
@@ -243,5 +273,5 @@ An integrated platform for running experiments, sharing workflows and launching
243
273
  - <a href="https://blog.expectedparrot.com" target="_blank" rel="noopener noreferrer">Blog</a>.
244
274
 
245
275
  ## Contact
246
- - <a href="mailto:info@expectedparrot.com" target="_blank" rel="noopener noreferrer">Email</a>
276
+ - <a href="mailto:info@expectedparrot.com" target="_blank" rel="noopener noreferrer">Email</a>.
247
277
 
@@ -142,6 +142,27 @@ results.select("color", "flower")
142
142
  **Caching**:
143
143
  API calls to LLMs are cached automatically, allowing you to retrieve responses to questions that have already been run and reproduce experiments at no cost. Learn more about how the <a href="https://docs.expectedparrot.com/en/latest/remote_caching.html" target="_blank" rel="noopener noreferrer">universal remote cache</a> works.
144
144
 
145
+ **Logging**:
146
+ EDSL includes a comprehensive logging system to help with debugging and monitoring. Control log levels and see important information about operations:
147
+
148
+ ```python
149
+ from edsl import logger
150
+ import logging
151
+
152
+ # Set the logging level
153
+ logger.set_level(logging.DEBUG) # Show all log messages
154
+
155
+ # Get a module-specific logger
156
+ my_logger = logger.get_logger(__name__)
157
+ my_logger.info("This is a module-specific log message")
158
+
159
+ # Log messages at different levels
160
+ logger.debug("Detailed debugging information")
161
+ logger.info("General information about operation")
162
+ logger.warning("Something unexpected but not critical")
163
+ logger.error("Something went wrong")
164
+ ```
165
+
145
166
  **Flexibility**:
146
167
  Choose whether to run surveys on your own computer or at the Expected Parrot server.
147
168
 
@@ -175,6 +196,13 @@ Analyze results as specified datasets from your account or workspace. Easily imp
175
196
  - API keys for language models. You can use your own keys or an Expected Parrot key that provides access to all available models.
176
197
  See instructions on <a href="https://docs.expectedparrot.com/en/latest/api_keys.html" target="_blank" rel="noopener noreferrer">managing keys</a> and <a href="https://www.expectedparrot.com/getting-started/coop-pricing" target="_blank" rel="noopener noreferrer">model pricing and performance</a> information.
177
198
 
199
+ ## Developer Notes
200
+
201
+ ### Running Tests
202
+ - Unit tests: `python -m pytest tests/`
203
+ - Integration tests: `python -m pytest integration/`
204
+ - Doctests: `python run_doctests.py` (use `-v` flag for verbose output)
205
+
178
206
  ## Coop
179
207
  An integrated platform for running experiments, sharing workflows and launching hybrid human/AI surveys.
180
208
  - <a href="https://www.expectedparrot.com/login" target="_blank" rel="noopener noreferrer">Login / Signup</a>
@@ -187,4 +215,4 @@ An integrated platform for running experiments, sharing workflows and launching
187
215
  - <a href="https://blog.expectedparrot.com" target="_blank" rel="noopener noreferrer">Blog</a>.
188
216
 
189
217
  ## Contact
190
- - <a href="mailto:info@expectedparrot.com" target="_blank" rel="noopener noreferrer">Email</a>
218
+ - <a href="mailto:info@expectedparrot.com" target="_blank" rel="noopener noreferrer">Email</a>.
@@ -0,0 +1,134 @@
1
+ import os
2
+ import time
3
+ import importlib
4
+ import pkgutil
5
+
6
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
7
+ ROOT_DIR = os.path.dirname(BASE_DIR)
8
+
9
+ from edsl.__version__ import __version__
10
+ from edsl.config import Config, CONFIG
11
+
12
+ # Initialize and expose logger
13
+ from edsl import logger
14
+
15
+ # Set up logger with configuration from environment/config
16
+ # (We'll configure the logger after CONFIG is initialized below)
17
+
18
+ __all__ = ['logger']
19
+
20
+ # Define modules to import
21
+ modules_to_import = [
22
+ 'dataset',
23
+ 'agents',
24
+ 'surveys',
25
+ 'questions',
26
+ 'scenarios',
27
+ 'language_models',
28
+ 'results',
29
+ 'caching',
30
+ 'notebooks',
31
+ 'coop',
32
+ 'instructions',
33
+ 'jobs'
34
+ ]
35
+
36
+ # Dynamically import modules and extend __all__
37
+ for module_name in modules_to_import:
38
+ try:
39
+ # Import the module
40
+ module = importlib.import_module(f'.{module_name}', package='edsl')
41
+
42
+ # Get the module's __all__ attribute
43
+ module_all = getattr(module, '__all__', [])
44
+
45
+ # Import all names from the module
46
+ exec(f"from .{module_name} import *")
47
+
48
+ # Extend __all__ with the module's __all__
49
+ if module_all:
50
+ logger.debug(f"Adding {len(module_all)} items from {module_name} to __all__")
51
+ __all__.extend(module_all)
52
+ else:
53
+ logger.warning(f"Module {module_name} does not have __all__ defined")
54
+ except ImportError as e:
55
+ logger.warning(f"Failed to import module {module_name}: {e}")
56
+ except Exception as e:
57
+ logger.warning(f"Error importing from module {module_name}: {e}")
58
+
59
+
60
+ # Load plugins
61
+ try:
62
+ from edsl.load_plugins import load_plugins
63
+ from edsl.plugins import get_plugin_manager, get_exports
64
+
65
+ # Load all plugins
66
+ plugins = load_plugins()
67
+ logger.info(f"Loaded {len(plugins)} plugins")
68
+
69
+ # Add plugins to globals and __all__
70
+ for plugin_name, plugin in plugins.items():
71
+ globals()[plugin_name] = plugin
72
+ __all__.append(plugin_name)
73
+ logger.info(f"Registered plugin {plugin_name} in global namespace")
74
+
75
+ # Get exports from plugins and add them to globals
76
+ exports = get_exports()
77
+ logger.info(f"Found {len(exports)} exported objects from plugins")
78
+
79
+ for name, obj in exports.items():
80
+ globals()[name] = obj
81
+ __all__.append(name)
82
+ logger.info(f"Added plugin export: {name}")
83
+
84
+ # Add placeholders for expected exports that are missing
85
+ # This maintains backward compatibility for common plugins
86
+ PLUGIN_PLACEHOLDERS = {
87
+ # No placeholders - removed Conjure for cleaner namespace
88
+ }
89
+
90
+ for placeholder_name, github_url in PLUGIN_PLACEHOLDERS.items():
91
+ if placeholder_name not in globals():
92
+ # Create a placeholder class
93
+ placeholder_class = type(placeholder_name, (), {
94
+ "__getattr__": lambda self, name: self._not_installed(name),
95
+ "_not_installed": lambda self, name: self._raise_import_error(),
96
+ "_raise_import_error": lambda self: exec(f"""
97
+ msg = (
98
+ "The {placeholder_name} plugin is not installed. "
99
+ "To use {placeholder_name} with EDSL, install it using:\\n"
100
+ " from edsl.plugins import install_from_github\\n"
101
+ " install_from_github('{github_url}')\\n"
102
+ "\\nOr from the command line:\\n"
103
+ " edsl plugins install {github_url}"
104
+ )
105
+ logger.warning(msg)
106
+ raise ImportError(msg)
107
+ """)
108
+ })
109
+
110
+ # Register the placeholder
111
+ globals()[placeholder_name] = placeholder_class()
112
+ __all__.append(placeholder_name)
113
+ logger.info(f"Added placeholder for {placeholder_name} with installation instructions")
114
+
115
+ except ImportError as e:
116
+ # Modules not available
117
+ logger.info("Plugin system not available, skipping plugin loading: %s", e)
118
+ logger.debug("Plugin system not available, skipping plugin loading: %s", e)
119
+ except Exception as e:
120
+ # Error loading plugins
121
+ logger.error("Error loading plugins: %s", e)
122
+ logger.debug("Error loading plugins: %s", e)
123
+
124
+ # Now that all modules are loaded, configure logging from the config
125
+ logger.configure_from_config()
126
+
127
+
128
+ # Installs a custom exception handling routine for edsl exceptions
129
+ from .base.base_exception import BaseException
130
+ BaseException.install_exception_hook()
131
+
132
+ # Log the total number of items in __all__ for debugging
133
+ logger.debug(f"EDSL initialization complete with {len(__all__)} items in __all__")
134
+
@@ -0,0 +1 @@
1
+ __version__ = "0.1.51"
@@ -47,7 +47,6 @@ import types
47
47
  import warnings
48
48
  from uuid import uuid4
49
49
  from contextlib import contextmanager
50
-
51
50
  from typing import (
52
51
  Callable,
53
52
  Optional,
@@ -57,11 +56,9 @@ from typing import (
57
56
  Protocol,
58
57
  runtime_checkable,
59
58
  TypeVar,
59
+ Type,
60
60
  )
61
61
 
62
- # Type variable for the Agent class
63
- A = TypeVar("A", bound="Agent")
64
-
65
62
  if TYPE_CHECKING:
66
63
  from ..caching import Cache
67
64
  from ..surveys import Survey
@@ -71,17 +68,8 @@ if TYPE_CHECKING:
71
68
  from ..questions import QuestionBase
72
69
  from ..invigilators import InvigilatorBase
73
70
  from ..prompts import Prompt
74
- from ..questions import QuestionBase
75
71
  from ..key_management import KeyLookup
76
72
 
77
-
78
- @runtime_checkable
79
- class DirectAnswerMethod(Protocol):
80
- """Protocol defining the required signature for direct answer methods."""
81
-
82
- def __call__(self, self_: A, question: QuestionBase, scenario: Scenario) -> Any: ...
83
-
84
-
85
73
  from ..base import Base
86
74
  from ..scenarios import Scenario
87
75
  from ..questions import QuestionScenarioRenderError
@@ -93,7 +81,6 @@ from ..utilities import (
93
81
  remove_edsl_version,
94
82
  )
95
83
 
96
-
97
84
  from .exceptions import (
98
85
  AgentErrors,
99
86
  AgentCombinationError,
@@ -108,6 +95,16 @@ from .descriptors import (
108
95
  NameDescriptor,
109
96
  )
110
97
 
98
+ # Type variable for the Agent class
99
+ A = TypeVar("A", bound="Agent")
100
+
101
+
102
+ @runtime_checkable
103
+ class DirectAnswerMethod(Protocol):
104
+ """Protocol defining the required signature for direct answer methods."""
105
+
106
+ def __call__(self, self_: A, question: QuestionBase, scenario: Scenario) -> Any: ...
107
+
111
108
 
112
109
  class AgentTraits(Scenario):
113
110
  """A class representing the traits of an agent.
@@ -472,9 +469,10 @@ class Agent(Base):
472
469
  # Transfer direct answering method if present
473
470
  if hasattr(self, "answer_question_directly"):
474
471
  answer_question_directly = self.answer_question_directly
475
- newf = lambda self, question, scenario: answer_question_directly(
476
- question, scenario
477
- )
472
+ def newf(self, question, scenario):
473
+ return answer_question_directly(
474
+ question, scenario
475
+ )
478
476
  new_agent.add_direct_question_answering_method(newf)
479
477
 
480
478
  # Transfer dynamic traits function if present
@@ -940,7 +938,7 @@ class Agent(Base):
940
938
 
941
939
  answer_question = sync_wrapper(async_answer_question)
942
940
 
943
- def _get_invigilator_class(self, question: QuestionBase) -> Type[InvigilatorBase]:
941
+ def _get_invigilator_class(self, question: "QuestionBase") -> Type["InvigilatorBase"]:
944
942
  """Get the invigilator class for a question.
945
943
 
946
944
  This method returns the invigilator class that should be used to answer a question.
@@ -1098,6 +1096,8 @@ class Agent(Base):
1098
1096
  if name in self._traits:
1099
1097
  return self._traits[name]
1100
1098
 
1099
+ # Keep using AttributeError instead of our custom exception to maintain compatibility
1100
+ # with Python's attribute access mechanism
1101
1101
  raise AttributeError(
1102
1102
  f"'{type(self).__name__}' object has no attribute '{name}'"
1103
1103
  )
@@ -1142,7 +1142,7 @@ class Agent(Base):
1142
1142
  raw_data.pop("instruction")
1143
1143
  if self.codebook == {}:
1144
1144
  raw_data.pop("codebook")
1145
- if self.name == None:
1145
+ if self.name is None:
1146
1146
  raw_data.pop("name")
1147
1147
 
1148
1148
  if hasattr(self, "dynamic_traits_function"):
@@ -1164,7 +1164,7 @@ class Agent(Base):
1164
1164
 
1165
1165
  if (
1166
1166
  answer_question_directly_func
1167
- and raw_data.get("answer_question_directly_source_code", None) != None
1167
+ and raw_data.get("answer_question_directly_source_code", None) is not None
1168
1168
  ):
1169
1169
  raw_data["answer_question_directly_source_code"] = inspect.getsource(
1170
1170
  answer_question_directly_func
@@ -1352,7 +1352,7 @@ def main():
1352
1352
  question_name="food_preference",
1353
1353
  )
1354
1354
  job = question.by(agent)
1355
- results = job.run()
1355
+ job.run() # results not used
1356
1356
 
1357
1357
 
1358
1358
  if __name__ == "__main__":
@@ -27,10 +27,7 @@ from .exceptions import AgentListError
27
27
  logger = logging.getLogger(__name__)
28
28
 
29
29
  if TYPE_CHECKING:
30
- from ..scenarios import ScenarioList
31
30
  from ..agents import Agent
32
- from pandas import DataFrame
33
- from ..dataset import Dataset
34
31
 
35
32
 
36
33
  def is_iterable(obj):
@@ -212,7 +209,7 @@ class AgentList(UserList, Base, AgentListOperationsMixin):
212
209
  new_data = [
213
210
  agent for agent in self.data if create_evaluator(agent).eval(expression)
214
211
  ]
215
- except NameNotDefined as e:
212
+ except NameNotDefined:
216
213
  e = AgentListError(f"'{expression}' is not a valid expression.")
217
214
  if is_notebook():
218
215
  print(e, file=sys.stderr)
@@ -451,7 +448,7 @@ class AgentList(UserList, Base, AgentListOperationsMixin):
451
448
  *fields,
452
449
  tablefmt: Optional[str] = None,
453
450
  pretty_labels: Optional[dict] = None,
454
- ) -> "Table":
451
+ ) -> Any:
455
452
  if len(self) == 0:
456
453
  e = AgentListError("Cannot create a table from an empty AgentList.")
457
454
  if is_notebook():
@@ -0,0 +1,159 @@
1
+
2
+ from ..base.base_exception import BaseException
3
+
4
+
5
+ class AgentListError(BaseException):
6
+ """
7
+ Exception raised when an AgentList operation fails.
8
+
9
+ This exception is raised in the following cases:
10
+ - When an invalid expression is provided in the filter() method
11
+ - When trying to add traits with mismatched lengths
12
+ - When attempting to create a table from an empty AgentList
13
+
14
+ Examples:
15
+ ```python
16
+ agents.filter("invalid expression") # Raises AgentListError
17
+ agents.add_trait(name="scores", values=[1, 2]) # Raises AgentListError if agents list has different length
18
+ ```
19
+ """
20
+ relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html#agent-lists"
21
+
22
+
23
+ class AgentErrors(BaseException):
24
+ """
25
+ Base exception class for all agent-related errors.
26
+
27
+ This class is the parent of all agent-specific exceptions and may also be raised directly
28
+ when modifying agent traits or during operations like renaming or adding traits.
29
+ """
30
+ relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html"
31
+
32
+
33
+ class AgentDynamicTraitsFunctionError(AgentErrors):
34
+ """
35
+ Exception raised when there's an issue with the dynamic traits function.
36
+
37
+ This exception occurs when:
38
+ - The dynamic traits function has too many parameters
39
+ - The dynamic traits function has parameters other than 'question'
40
+
41
+ This error typically indicates that your dynamic traits function has an incorrect signature.
42
+ The function should accept only one parameter named 'question'.
43
+
44
+ Examples:
45
+ ```python
46
+ def wrong_func(question, extra_param): # Will raise AgentDynamicTraitsFunctionError
47
+ return {"trait": "value"}
48
+ ```
49
+ """
50
+ relevant_doc = (
51
+ "https://docs.expectedparrot.com/en/latest/agents.html#dynamic-traits-function"
52
+ )
53
+ relevant_notebook = "https://docs.expectedparrot.com/en/latest/notebooks/example_agent_dynamic_traits.html"
54
+
55
+
56
+ class AgentDirectAnswerFunctionError(AgentErrors):
57
+ """
58
+ Exception raised when there's an issue with the direct answer method.
59
+
60
+ This exception occurs when the direct answer method doesn't have the required parameters.
61
+ The method must include 'question', 'scenario', and/or 'self' parameters.
62
+
63
+ Examples:
64
+ ```python
65
+ def wrong_answer_func(wrong_param): # Will raise AgentDirectAnswerFunctionError
66
+ return "Answer"
67
+ ```
68
+ """
69
+ relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html#agent-direct-answering-methods"
70
+
71
+
72
+ class AgentCombinationError(AgentErrors):
73
+ """
74
+ Exception raised when attempting to combine agents with overlapping traits.
75
+
76
+ This exception occurs when you try to combine agents that have the same trait names,
77
+ which would result in ambiguous trait values in the combined agent.
78
+
79
+ To fix this, ensure that the agents being combined have unique trait names,
80
+ or rename the conflicting traits before combination.
81
+
82
+ Examples:
83
+ ```python
84
+ agent1 = Agent(name="A1", age=30)
85
+ agent2 = Agent(name="A2", age=40)
86
+ agent1 + agent2 # Raises AgentCombinationError due to duplicate 'age' trait
87
+ ```
88
+ """
89
+ relevant_doc = (
90
+ "https://docs.expectedparrot.com/en/latest/agents.html#combining-agents"
91
+ )
92
+
93
+
94
+ class AgentNameError(AgentErrors):
95
+ """
96
+ Exception raised when there's an issue with an agent's name.
97
+
98
+ This exception occurs when a trait key conflicts with the 'name' parameter,
99
+ as 'name' is a special attribute for agents and cannot be used as a trait name.
100
+
101
+ Examples:
102
+ ```python
103
+ Agent(name="John", name="John") # Raises AgentNameError
104
+ agent.add_trait(name="name", value="NewName") # Raises AgentNameError
105
+ ```
106
+ """
107
+ relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html#agent-names"
108
+
109
+
110
+ class AgentTraitKeyError(AgentErrors):
111
+ """
112
+ Exception raised when an invalid trait key is used.
113
+
114
+ This exception occurs when a trait key is not a valid Python identifier.
115
+ Trait keys must follow Python variable naming rules (no spaces, no special characters
116
+ except underscore, cannot start with a number).
117
+
118
+ Examples:
119
+ ```python
120
+ Agent(name="John", "invalid-key"=30) # Raises AgentTraitKeyError
121
+ agent.add_trait(name="2invalid", value="value") # Raises AgentTraitKeyError
122
+ ```
123
+ """
124
+ relevant_doc = (
125
+ "https://docs.expectedparrot.com/en/latest/agents.html#constructing-an-agent"
126
+ )
127
+
128
+
129
+ class AgentAttributeError(AgentErrors):
130
+ """
131
+ Exception raised when accessing a non-existent attribute of an agent.
132
+
133
+ This exception occurs when trying to access a trait or attribute that
134
+ doesn't exist on the agent.
135
+
136
+ Examples:
137
+ ```python
138
+ agent = Agent(name="John", age=30)
139
+ agent.height # Raises AgentAttributeError as 'height' doesn't exist
140
+ ```
141
+ """
142
+ relevant_doc = "https://docs.expectedparrot.com/en/latest/agents.html#agent-traits"
143
+
144
+ def __init__(self, message):
145
+ super().__init__(message)
146
+
147
+
148
+ class FailedTaskException(BaseException):
149
+ """
150
+ Exception raised when an agent task execution fails.
151
+
152
+ This exception is used to track agent execution failures and retain information
153
+ about the agent's response when the failure occurred.
154
+
155
+ Note: This exception class is currently not used in the codebase.
156
+ """
157
+ def __init__(self, message, agent_response_dict):
158
+ super().__init__(f"Agent task failed: {message}")
159
+ self.agent_response_dict = agent_response_dict
@@ -7,7 +7,6 @@ from edsl.base.base_class import (
7
7
  Base,
8
8
  BaseDiff,
9
9
  BaseDiffCollection,
10
- BaseException,
11
10
  DiffMethodsMixin,
12
11
  DisplayJSON,
13
12
  DisplayYAML,
@@ -18,6 +17,15 @@ from edsl.base.base_class import (
18
17
  RepresentationMixin,
19
18
  is_iterable,
20
19
  )
20
+ from edsl.base.base_exception import BaseException
21
+ from edsl.base.exceptions import (
22
+ BaseValueError,
23
+ BaseNotImplementedError,
24
+ BaseKeyError,
25
+ BaseFileError,
26
+ BaseTypeError
27
+ )
28
+
21
29
  from edsl.base.enums import (
22
30
  EnumWithChecks,
23
31
  InferenceServiceLiteral,
@@ -39,37 +47,4 @@ from edsl.base.data_transfer_models import (
39
47
  ModelResponse,
40
48
  )
41
49
 
42
- __all__ = [
43
- # From base_class
44
- "Base",
45
- "BaseDiff",
46
- "BaseDiffCollection",
47
- "BaseException",
48
- "DiffMethodsMixin",
49
- "DisplayJSON",
50
- "DisplayYAML",
51
- "DummyObject",
52
- "HashingMixin",
53
- "PersistenceMixin",
54
- "RegisterSubclassesMeta",
55
- "RepresentationMixin",
56
- "is_iterable",
57
- # From enums
58
- "EnumWithChecks",
59
- "InferenceServiceLiteral",
60
- "InferenceServiceType",
61
- "QuestionType",
62
- "TokenPricing",
63
- "available_models_urls",
64
- "get_token_pricing",
65
- "pricing",
66
- "service_to_api_keyname",
67
- # From data_transfer_models
68
- "AgentResponseDict",
69
- "Answers",
70
- "EDSLOutput",
71
- "EDSLResultObjectInput",
72
- "ImageInfo",
73
- "ModelInputs",
74
- "ModelResponse",
75
- ]
50
+ __all__ = []