edsl 0.1.58__tar.gz → 0.1.60__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 (391) hide show
  1. {edsl-0.1.58 → edsl-0.1.60}/PKG-INFO +5 -4
  2. {edsl-0.1.58 → edsl-0.1.60}/README.md +1 -1
  3. edsl-0.1.60/edsl/__version__.py +1 -0
  4. {edsl-0.1.58 → edsl-0.1.60}/edsl/agents/agent.py +23 -4
  5. {edsl-0.1.58 → edsl-0.1.60}/edsl/agents/agent_list.py +36 -6
  6. {edsl-0.1.58 → edsl-0.1.60}/edsl/base/data_transfer_models.py +5 -0
  7. {edsl-0.1.58 → edsl-0.1.60}/edsl/base/enums.py +7 -2
  8. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/coop.py +103 -1
  9. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/dataset.py +74 -0
  10. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/dataset_operations_mixin.py +69 -64
  11. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/__init__.py +3 -1
  12. edsl-0.1.60/edsl/inference_services/services/open_ai_service_v2.py +243 -0
  13. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/test_service.py +1 -1
  14. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/exception_tracking.py +66 -20
  15. {edsl-0.1.58 → edsl-0.1.60}/edsl/invigilators/invigilators.py +5 -1
  16. {edsl-0.1.58 → edsl-0.1.60}/edsl/invigilators/prompt_constructor.py +299 -136
  17. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/data_structures.py +3 -0
  18. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/html_table_job_logger.py +18 -1
  19. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/jobs_pricing_estimation.py +6 -2
  20. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/jobs_remote_inference_logger.py +2 -0
  21. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/remote_inference.py +34 -7
  22. {edsl-0.1.58 → edsl-0.1.60}/edsl/key_management/key_lookup_builder.py +25 -3
  23. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/language_model.py +41 -3
  24. edsl-0.1.60/edsl/language_models/raw_response_handler.py +230 -0
  25. {edsl-0.1.58 → edsl-0.1.60}/edsl/prompts/prompt.py +1 -0
  26. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_list.py +76 -20
  27. {edsl-0.1.58 → edsl-0.1.60}/edsl/results/result.py +37 -0
  28. {edsl-0.1.58 → edsl-0.1.60}/edsl/results/results.py +9 -1
  29. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/file_store.py +8 -12
  30. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/scenario.py +50 -2
  31. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/scenario_list.py +34 -12
  32. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/survey.py +4 -0
  33. {edsl-0.1.58 → edsl-0.1.60}/edsl/tasks/task_history.py +180 -6
  34. edsl-0.1.60/edsl/utilities/wikipedia.py +194 -0
  35. {edsl-0.1.58 → edsl-0.1.60}/pyproject.toml +3 -3
  36. edsl-0.1.58/edsl/__version__.py +0 -1
  37. edsl-0.1.58/edsl/language_models/raw_response_handler.py +0 -111
  38. {edsl-0.1.58 → edsl-0.1.60}/LICENSE +0 -0
  39. {edsl-0.1.58 → edsl-0.1.60}/edsl/__init__.py +0 -0
  40. {edsl-0.1.58 → edsl-0.1.60}/edsl/__init__original.py +0 -0
  41. {edsl-0.1.58 → edsl-0.1.60}/edsl/agents/__init__.py +0 -0
  42. {edsl-0.1.58 → edsl-0.1.60}/edsl/agents/descriptors.py +0 -0
  43. {edsl-0.1.58 → edsl-0.1.60}/edsl/agents/exceptions.py +0 -0
  44. {edsl-0.1.58 → edsl-0.1.60}/edsl/base/__init__.py +0 -0
  45. {edsl-0.1.58 → edsl-0.1.60}/edsl/base/base_class.py +0 -0
  46. {edsl-0.1.58 → edsl-0.1.60}/edsl/base/base_exception.py +0 -0
  47. {edsl-0.1.58 → edsl-0.1.60}/edsl/base/exceptions.py +0 -0
  48. {edsl-0.1.58 → edsl-0.1.60}/edsl/base.py +0 -0
  49. {edsl-0.1.58 → edsl-0.1.60}/edsl/buckets/__init__.py +0 -0
  50. {edsl-0.1.58 → edsl-0.1.60}/edsl/buckets/bucket_collection.py +0 -0
  51. {edsl-0.1.58 → edsl-0.1.60}/edsl/buckets/exceptions.py +0 -0
  52. {edsl-0.1.58 → edsl-0.1.60}/edsl/buckets/model_buckets.py +0 -0
  53. {edsl-0.1.58 → edsl-0.1.60}/edsl/buckets/token_bucket.py +0 -0
  54. {edsl-0.1.58 → edsl-0.1.60}/edsl/buckets/token_bucket_api.py +0 -0
  55. {edsl-0.1.58 → edsl-0.1.60}/edsl/buckets/token_bucket_client.py +0 -0
  56. {edsl-0.1.58 → edsl-0.1.60}/edsl/caching/__init__.py +0 -0
  57. {edsl-0.1.58 → edsl-0.1.60}/edsl/caching/cache.py +0 -0
  58. {edsl-0.1.58 → edsl-0.1.60}/edsl/caching/cache_entry.py +0 -0
  59. {edsl-0.1.58 → edsl-0.1.60}/edsl/caching/cache_handler.py +0 -0
  60. {edsl-0.1.58 → edsl-0.1.60}/edsl/caching/exceptions.py +0 -0
  61. {edsl-0.1.58 → edsl-0.1.60}/edsl/caching/orm.py +0 -0
  62. {edsl-0.1.58 → edsl-0.1.60}/edsl/caching/remote_cache_sync.py +0 -0
  63. {edsl-0.1.58 → edsl-0.1.60}/edsl/caching/sql_dict.py +0 -0
  64. {edsl-0.1.58 → edsl-0.1.60}/edsl/cli.py +0 -0
  65. {edsl-0.1.58 → edsl-0.1.60}/edsl/config/__init__.py +0 -0
  66. {edsl-0.1.58 → edsl-0.1.60}/edsl/config/config_class.py +0 -0
  67. {edsl-0.1.58 → edsl-0.1.60}/edsl/config.py +0 -0
  68. {edsl-0.1.58 → edsl-0.1.60}/edsl/conversation/Conversation.py +0 -0
  69. {edsl-0.1.58 → edsl-0.1.60}/edsl/conversation/__init__.py +0 -0
  70. {edsl-0.1.58 → edsl-0.1.60}/edsl/conversation/car_buying.py +0 -0
  71. {edsl-0.1.58 → edsl-0.1.60}/edsl/conversation/chips.py +0 -0
  72. {edsl-0.1.58 → edsl-0.1.60}/edsl/conversation/exceptions.py +0 -0
  73. {edsl-0.1.58 → edsl-0.1.60}/edsl/conversation/mug_negotiation.py +0 -0
  74. {edsl-0.1.58 → edsl-0.1.60}/edsl/conversation/next_speaker_utilities.py +0 -0
  75. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/__init__.py +0 -0
  76. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/coop_functions.py +0 -0
  77. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/coop_jobs_objects.py +0 -0
  78. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/coop_objects.py +0 -0
  79. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/coop_regular_objects.py +0 -0
  80. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/ep_key_handling.py +0 -0
  81. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/exceptions.py +0 -0
  82. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/price_fetcher.py +0 -0
  83. {edsl-0.1.58 → edsl-0.1.60}/edsl/coop/utils.py +0 -0
  84. {edsl-0.1.58 → edsl-0.1.60}/edsl/data_transfer_models.py +0 -0
  85. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/__init__.py +0 -0
  86. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/dataset_tree.py +0 -0
  87. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/display/CSSParameterizer.py +0 -0
  88. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/display/__init__.py +0 -0
  89. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/display/table_data_class.py +0 -0
  90. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/display/table_display.css +0 -0
  91. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/display/table_display.py +0 -0
  92. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/display/table_renderers.py +0 -0
  93. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/exceptions.py +0 -0
  94. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/file_exports.py +0 -0
  95. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/r/ggplot.py +0 -0
  96. {edsl-0.1.58 → edsl-0.1.60}/edsl/dataset/tree_explore.py +0 -0
  97. {edsl-0.1.58 → edsl-0.1.60}/edsl/db_list/sqlite_list.py +0 -0
  98. {edsl-0.1.58 → edsl-0.1.60}/edsl/display/__init__.py +0 -0
  99. {edsl-0.1.58 → edsl-0.1.60}/edsl/display/core.py +0 -0
  100. {edsl-0.1.58 → edsl-0.1.60}/edsl/display/plugin.py +0 -0
  101. {edsl-0.1.58 → edsl-0.1.60}/edsl/display/utils.py +0 -0
  102. {edsl-0.1.58 → edsl-0.1.60}/edsl/enums.py +0 -0
  103. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/__init__.py +0 -0
  104. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/available_model_cache_handler.py +0 -0
  105. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/available_model_fetcher.py +0 -0
  106. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/data_structures.py +0 -0
  107. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/exceptions.py +0 -0
  108. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/inference_service_abc.py +0 -0
  109. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/inference_services_collection.py +0 -0
  110. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/models_available_cache.py +0 -0
  111. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/rate_limits_cache.py +0 -0
  112. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/registry.py +0 -0
  113. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/service_availability.py +0 -0
  114. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/anthropic_service.py +0 -0
  115. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/aws_bedrock.py +0 -0
  116. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/azure_ai.py +0 -0
  117. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/deep_infra_service.py +0 -0
  118. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/deep_seek_service.py +0 -0
  119. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/google_service.py +0 -0
  120. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/groq_service.py +0 -0
  121. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/mistral_ai_service.py +0 -0
  122. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/ollama_service.py +0 -0
  123. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/open_ai_service.py +0 -0
  124. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/perplexity_service.py +0 -0
  125. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/together_ai_service.py +0 -0
  126. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/services/xai_service.py +0 -0
  127. {edsl-0.1.58 → edsl-0.1.60}/edsl/inference_services/write_available.py +0 -0
  128. {edsl-0.1.58 → edsl-0.1.60}/edsl/instructions/__init__.py +0 -0
  129. {edsl-0.1.58 → edsl-0.1.60}/edsl/instructions/change_instruction.py +0 -0
  130. {edsl-0.1.58 → edsl-0.1.60}/edsl/instructions/exceptions.py +0 -0
  131. {edsl-0.1.58 → edsl-0.1.60}/edsl/instructions/instruction.py +0 -0
  132. {edsl-0.1.58 → edsl-0.1.60}/edsl/instructions/instruction_collection.py +0 -0
  133. {edsl-0.1.58 → edsl-0.1.60}/edsl/instructions/instruction_handler.py +0 -0
  134. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/ReportErrors.py +0 -0
  135. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/__init__.py +0 -0
  136. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/answering_function.py +0 -0
  137. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/exceptions.py +0 -0
  138. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/interview.py +0 -0
  139. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/interview_status_dictionary.py +0 -0
  140. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/interview_status_enum.py +0 -0
  141. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/interview_status_log.py +0 -0
  142. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/interview_task_manager.py +0 -0
  143. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/request_token_estimator.py +0 -0
  144. {edsl-0.1.58 → edsl-0.1.60}/edsl/interviews/statistics.py +0 -0
  145. {edsl-0.1.58 → edsl-0.1.60}/edsl/invigilators/__init__.py +0 -0
  146. {edsl-0.1.58 → edsl-0.1.60}/edsl/invigilators/exceptions.py +0 -0
  147. {edsl-0.1.58 → edsl-0.1.60}/edsl/invigilators/invigilator_base.py +0 -0
  148. {edsl-0.1.58 → edsl-0.1.60}/edsl/invigilators/prompt_helpers.py +0 -0
  149. {edsl-0.1.58 → edsl-0.1.60}/edsl/invigilators/question_instructions_prompt_builder.py +0 -0
  150. {edsl-0.1.58 → edsl-0.1.60}/edsl/invigilators/question_option_processor.py +0 -0
  151. {edsl-0.1.58 → edsl-0.1.60}/edsl/invigilators/question_template_replacements_builder.py +0 -0
  152. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/__init__.py +0 -0
  153. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/async_interview_runner.py +0 -0
  154. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/check_survey_scenario_compatibility.py +0 -0
  155. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/decorators.py +0 -0
  156. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/exceptions.py +0 -0
  157. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/fetch_invigilator.py +0 -0
  158. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/jobs.py +0 -0
  159. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/jobs_checks.py +0 -0
  160. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/jobs_component_constructor.py +0 -0
  161. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/jobs_interview_constructor.py +0 -0
  162. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/jobs_runner_status.py +0 -0
  163. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/jobs_status_enums.py +0 -0
  164. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/progress_bar_manager.py +0 -0
  165. {edsl-0.1.58 → edsl-0.1.60}/edsl/jobs/results_exceptions_handler.py +0 -0
  166. {edsl-0.1.58 → edsl-0.1.60}/edsl/key_management/__init__.py +0 -0
  167. {edsl-0.1.58 → edsl-0.1.60}/edsl/key_management/exceptions.py +0 -0
  168. {edsl-0.1.58 → edsl-0.1.60}/edsl/key_management/key_lookup.py +0 -0
  169. {edsl-0.1.58 → edsl-0.1.60}/edsl/key_management/key_lookup_collection.py +0 -0
  170. {edsl-0.1.58 → edsl-0.1.60}/edsl/key_management/models.py +0 -0
  171. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/__init__.py +0 -0
  172. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/exceptions.py +0 -0
  173. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/model.py +0 -0
  174. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/model_list.py +0 -0
  175. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/price_manager.py +0 -0
  176. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/registry.py +0 -0
  177. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/repair.py +0 -0
  178. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/unused/fake_openai_call.py +0 -0
  179. {edsl-0.1.58 → edsl-0.1.60}/edsl/language_models/utilities.py +0 -0
  180. {edsl-0.1.58 → edsl-0.1.60}/edsl/load_plugins.py +0 -0
  181. {edsl-0.1.58 → edsl-0.1.60}/edsl/logger.py +0 -0
  182. {edsl-0.1.58 → edsl-0.1.60}/edsl/notebooks/__init__.py +0 -0
  183. {edsl-0.1.58 → edsl-0.1.60}/edsl/notebooks/exceptions.py +0 -0
  184. {edsl-0.1.58 → edsl-0.1.60}/edsl/notebooks/notebook.py +0 -0
  185. {edsl-0.1.58 → edsl-0.1.60}/edsl/notebooks/notebook_to_latex.py +0 -0
  186. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/__init__.py +0 -0
  187. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/built_in/export_example.py +0 -0
  188. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/built_in/pig_latin.py +0 -0
  189. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/cli.py +0 -0
  190. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/cli_typer.py +0 -0
  191. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/exceptions.py +0 -0
  192. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/hookspec.py +0 -0
  193. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/plugin_host.py +0 -0
  194. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/plugin_manager.py +0 -0
  195. {edsl-0.1.58 → edsl-0.1.60}/edsl/plugins/plugins_registry.py +0 -0
  196. {edsl-0.1.58 → edsl-0.1.60}/edsl/prompts/__init__.py +0 -0
  197. {edsl-0.1.58 → edsl-0.1.60}/edsl/prompts/exceptions.py +0 -0
  198. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/ExceptionExplainer.py +0 -0
  199. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/HTMLQuestion.py +0 -0
  200. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/Quick.py +0 -0
  201. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/VALIDATION_README.md +0 -0
  202. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/__init__.py +0 -0
  203. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/answer_validator_mixin.py +0 -0
  204. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/compose_questions.py +0 -0
  205. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/data_structures.py +0 -0
  206. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/decorators.py +0 -0
  207. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/descriptors.py +0 -0
  208. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/exceptions.py +0 -0
  209. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/loop_processor.py +0 -0
  210. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/prompt_templates/question_budget.jinja +0 -0
  211. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/prompt_templates/question_checkbox.jinja +0 -0
  212. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/prompt_templates/question_extract.jinja +0 -0
  213. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/prompt_templates/question_free_text.jinja +0 -0
  214. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/prompt_templates/question_linear_scale.jinja +0 -0
  215. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/prompt_templates/question_list.jinja +0 -0
  216. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/prompt_templates/question_multiple_choice.jinja +0 -0
  217. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/prompt_templates/question_numerical.jinja +0 -0
  218. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_base.py +0 -0
  219. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_base_gen_mixin.py +0 -0
  220. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_base_prompts_mixin.py +0 -0
  221. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_budget.py +0 -0
  222. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_check_box.py +0 -0
  223. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_dict.py +0 -0
  224. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_extract.py +0 -0
  225. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_free_text.py +0 -0
  226. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_functional.py +0 -0
  227. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_likert_five.py +0 -0
  228. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_linear_scale.py +0 -0
  229. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_matrix.py +0 -0
  230. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_multiple_choice.py +0 -0
  231. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_multiple_choice_with_other.py +0 -0
  232. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_numerical.py +0 -0
  233. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_rank.py +0 -0
  234. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_registry.py +0 -0
  235. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_top_k.py +0 -0
  236. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/question_yes_no.py +0 -0
  237. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/register_questions_meta.py +0 -0
  238. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/response_validator_abc.py +0 -0
  239. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/response_validator_factory.py +0 -0
  240. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/settings.py +0 -0
  241. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/simple_ask_mixin.py +0 -0
  242. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/__init__.py +0 -0
  243. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/budget/__init__.py +0 -0
  244. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/budget/answering_instructions.jinja +0 -0
  245. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/budget/question_presentation.jinja +0 -0
  246. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/checkbox/__init__.py +0 -0
  247. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/checkbox/answering_instructions.jinja +0 -0
  248. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/checkbox/question_presentation.jinja +0 -0
  249. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/dict/__init__.py +0 -0
  250. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/dict/answering_instructions.jinja +0 -0
  251. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/dict/question_presentation.jinja +0 -0
  252. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/extract/__init__.py +0 -0
  253. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/extract/answering_instructions.jinja +0 -0
  254. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/extract/question_presentation.jinja +0 -0
  255. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/free_text/__init__.py +0 -0
  256. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/free_text/answering_instructions.jinja +0 -0
  257. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/free_text/question_presentation.jinja +0 -0
  258. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/likert_five/__init__.py +0 -0
  259. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/likert_five/answering_instructions.jinja +0 -0
  260. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/likert_five/question_presentation.jinja +0 -0
  261. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/linear_scale/__init__.py +0 -0
  262. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/linear_scale/answering_instructions.jinja +0 -0
  263. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/linear_scale/question_presentation.jinja +0 -0
  264. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/list/__init__.py +0 -0
  265. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/list/answering_instructions.jinja +0 -0
  266. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/list/question_presentation.jinja +0 -0
  267. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/matrix/__init__.py +0 -0
  268. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/matrix/answering_instructions.jinja +0 -0
  269. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/matrix/question_presentation.jinja +0 -0
  270. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/multiple_choice/__init__.py +0 -0
  271. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/multiple_choice/answering_instructions.jinja +0 -0
  272. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/multiple_choice/html.jinja +0 -0
  273. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/multiple_choice/question_presentation.jinja +0 -0
  274. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/multiple_choice_with_other/__init__.py +0 -0
  275. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/multiple_choice_with_other/answering_instructions.jinja +0 -0
  276. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/multiple_choice_with_other/question_presentation.jinja +0 -0
  277. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/numerical/__init__.py +0 -0
  278. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/numerical/answering_instructions.jinja +0 -0
  279. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/numerical/question_presentation.jinja +0 -0
  280. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/rank/__init__.py +0 -0
  281. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/rank/answering_instructions.jinja +0 -0
  282. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/rank/question_presentation.jinja +0 -0
  283. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/top_k/__init__.py +0 -0
  284. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/top_k/answering_instructions.jinja +0 -0
  285. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/top_k/question_presentation.jinja +0 -0
  286. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/yes_no/__init__.py +0 -0
  287. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/yes_no/answering_instructions.jinja +0 -0
  288. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/templates/yes_no/question_presentation.jinja +0 -0
  289. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/validation_analysis.py +0 -0
  290. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/validation_cli.py +0 -0
  291. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/validation_html_report.py +0 -0
  292. {edsl-0.1.58 → edsl-0.1.60}/edsl/questions/validation_logger.py +0 -0
  293. {edsl-0.1.58 → edsl-0.1.60}/edsl/results/__init__.py +0 -0
  294. {edsl-0.1.58 → edsl-0.1.60}/edsl/results/exceptions.py +0 -0
  295. {edsl-0.1.58 → edsl-0.1.60}/edsl/results/report.py +0 -0
  296. {edsl-0.1.58 → edsl-0.1.60}/edsl/results/results_selector.py +0 -0
  297. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/DocxScenario.py +0 -0
  298. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/PdfExtractor.py +0 -0
  299. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/__init__.py +0 -0
  300. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/construct_download_link.py +0 -0
  301. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/directory_scanner.py +0 -0
  302. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/document_chunker.py +0 -0
  303. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/exceptions.py +0 -0
  304. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/file_methods.py +0 -0
  305. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/__init__.py +0 -0
  306. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/csv_file_store.py +0 -0
  307. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/docx_file_store.py +0 -0
  308. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/html_file_store.py +0 -0
  309. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/jpeg_file_store.py +0 -0
  310. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/json_file_store.py +0 -0
  311. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/latex_file_store.py +0 -0
  312. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/md_file_store.py +0 -0
  313. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/mp4_file_store.py +0 -0
  314. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/pdf_file_store.py +0 -0
  315. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/png_file_store.py +0 -0
  316. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/pptx_file_store.py +0 -0
  317. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/py_file_store.py +0 -0
  318. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/sql_file_store.py +0 -0
  319. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/sqlite_file_store.py +0 -0
  320. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/txt_file_store.py +0 -0
  321. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/handlers/webm_file_store.py +0 -0
  322. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/scenario_join.py +0 -0
  323. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/scenario_list_gc_test.py +0 -0
  324. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/scenario_list_memory_test.py +0 -0
  325. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/scenario_list_pdf_tools.py +0 -0
  326. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/scenario_list_source_refactor.md +0 -0
  327. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/scenario_selector.py +0 -0
  328. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/scenario_source.py +0 -0
  329. {edsl-0.1.58 → edsl-0.1.60}/edsl/scenarios/tests/test_scenario_list_sources.py +0 -0
  330. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/__init__.py +0 -0
  331. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/base.py +0 -0
  332. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/dag/__init__.py +0 -0
  333. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/dag/construct_dag.py +0 -0
  334. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/dag/dag.py +0 -0
  335. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/descriptors.py +0 -0
  336. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/edit_survey.py +0 -0
  337. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/exceptions.py +0 -0
  338. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/memory/__init__.py +0 -0
  339. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/memory/memory.py +0 -0
  340. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/memory/memory_management.py +0 -0
  341. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/memory/memory_plan.py +0 -0
  342. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/rules/__init__.py +0 -0
  343. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/rules/rule.py +0 -0
  344. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/rules/rule_collection.py +0 -0
  345. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/rules/rule_manager.py +0 -0
  346. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/survey_css.py +0 -0
  347. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/survey_export.py +0 -0
  348. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/survey_flow_visualization.py +0 -0
  349. {edsl-0.1.58 → edsl-0.1.60}/edsl/surveys/survey_simulator.py +0 -0
  350. {edsl-0.1.58 → edsl-0.1.60}/edsl/tasks/__init__.py +0 -0
  351. {edsl-0.1.58 → edsl-0.1.60}/edsl/tasks/exceptions.py +0 -0
  352. {edsl-0.1.58 → edsl-0.1.60}/edsl/tasks/question_task_creator.py +0 -0
  353. {edsl-0.1.58 → edsl-0.1.60}/edsl/tasks/task_creators.py +0 -0
  354. {edsl-0.1.58 → edsl-0.1.60}/edsl/tasks/task_status_enum.py +0 -0
  355. {edsl-0.1.58 → edsl-0.1.60}/edsl/tasks/task_status_log.py +0 -0
  356. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/base.html +0 -0
  357. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/exceptions_by_model.html +0 -0
  358. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/exceptions_by_question_name.html +0 -0
  359. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/exceptions_by_type.html +0 -0
  360. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/exceptions_table.html +0 -0
  361. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/interview_details.html +0 -0
  362. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/interviews.html +0 -0
  363. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/overview.html +0 -0
  364. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/performance_plot.html +0 -0
  365. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/report.css +0 -0
  366. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/report.html +0 -0
  367. {edsl-0.1.58 → edsl-0.1.60}/edsl/templates/error_reporting/report.js +0 -0
  368. {edsl-0.1.58 → edsl-0.1.60}/edsl/tests/scenarios/test_ScenarioSource.py +0 -0
  369. {edsl-0.1.58 → edsl-0.1.60}/edsl/tests/scenarios/test_scenario_list_sources.py +0 -0
  370. {edsl-0.1.58 → edsl-0.1.60}/edsl/tokens/__init__.py +0 -0
  371. {edsl-0.1.58 → edsl-0.1.60}/edsl/tokens/exceptions.py +0 -0
  372. {edsl-0.1.58 → edsl-0.1.60}/edsl/tokens/interview_token_usage.py +0 -0
  373. {edsl-0.1.58 → edsl-0.1.60}/edsl/tokens/token_usage.py +0 -0
  374. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/PrettyList.py +0 -0
  375. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/SystemInfo.py +0 -0
  376. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/__init__.py +0 -0
  377. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/ast_utilities.py +0 -0
  378. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/decorators.py +0 -0
  379. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/gcp_bucket/__init__.py +0 -0
  380. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/gcp_bucket/cloud_storage.py +0 -0
  381. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/is_notebook.py +0 -0
  382. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/is_valid_variable_name.py +0 -0
  383. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/markdown_to_docx.py +0 -0
  384. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/markdown_to_pdf.py +0 -0
  385. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/memory_debugger.py +0 -0
  386. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/naming_utilities.py +0 -0
  387. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/remove_edsl_version.py +0 -0
  388. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/repair_functions.py +0 -0
  389. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/restricted_python.py +0 -0
  390. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/template_loader.py +0 -0
  391. {edsl-0.1.58 → edsl-0.1.60}/edsl/utilities/utilities.py +0 -0
@@ -1,18 +1,19 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.58
3
+ Version: 0.1.60
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
7
7
  Keywords: LLM,social science,surveys,user research
8
8
  Author: John Horton
9
9
  Author-email: info@expectedparrot.com
10
- Requires-Python: >=3.9.1,<3.13
10
+ Requires-Python: >=3.9.1,<3.14
11
11
  Classifier: License :: OSI Approved :: MIT License
12
12
  Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
16
17
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
18
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
18
19
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
@@ -42,7 +43,7 @@ Requires-Dist: pydot (>=2.0.0,<3.0.0)
42
43
  Requires-Dist: pygments (>=2.17.2,<3.0.0)
43
44
  Requires-Dist: pymupdf (>=1.25.5,<2.0.0)
44
45
  Requires-Dist: pypdf2 (>=3.0.1,<4.0.0)
45
- Requires-Dist: pyreadstat (>=1.2.7,<2.0.0)
46
+ Requires-Dist: pyreadstat (==1.2.8)
46
47
  Requires-Dist: python-docx (>=1.1.0,<2.0.0)
47
48
  Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
48
49
  Requires-Dist: python-pptx (>=1.0.2,<2.0.0)
@@ -249,5 +250,5 @@ Choose whether to run surveys on your own computer or at the Expected Parrot ser
249
250
  Easily share workflows and projects privately or publicly at Coop: an integrated platform for AI-based research. Your account comes with free credits for running surveys, and lets you securely share keys, track expenses and usage for your team.
250
251
 
251
252
  **Built-in tools for analyis**:
252
- Analyze results as specified datasets from your account or workspace. Easily import data to use with your surveys and export results..
253
+ Analyze results as specified datasets from your account or workspace. Easily import data to use with your surveys and export results.
253
254
 
@@ -189,4 +189,4 @@ Choose whether to run surveys on your own computer or at the Expected Parrot ser
189
189
  Easily share workflows and projects privately or publicly at Coop: an integrated platform for AI-based research. Your account comes with free credits for running surveys, and lets you securely share keys, track expenses and usage for your team.
190
190
 
191
191
  **Built-in tools for analyis**:
192
- Analyze results as specified datasets from your account or workspace. Easily import data to use with your surveys and export results..
192
+ Analyze results as specified datasets from your account or workspace. Easily import data to use with your surveys and export results.
@@ -0,0 +1 @@
1
+ __version__ = "0.1.60"
@@ -426,6 +426,25 @@ class Agent(Base):
426
426
  self.traits_presentation_template = "Your traits: {{traits}}"
427
427
  self.set_traits_presentation_template = False
428
428
 
429
+
430
+ def drop(self, field_name: str) -> Agent:
431
+ """Drop a field from the agent.
432
+
433
+ Args:
434
+ field_name: The name of the field to drop.
435
+ """
436
+ d = self.to_dict()
437
+ if field_name in d['traits']:
438
+ d['traits'].pop(field_name)
439
+ elif field_name in d:
440
+ d.pop(field_name)
441
+ else:
442
+ raise AgentErrors((f"Field '{field_name}' not found in agent"
443
+ f"Available fields: {d.keys()}"
444
+ f"Available traits: {d['traits'].keys()}"
445
+ ))
446
+ return Agent.from_dict(d)
447
+
429
448
  def duplicate(self) -> Agent:
430
449
  """Create a deep copy of this agent with all its traits and capabilities.
431
450
 
@@ -1213,7 +1232,7 @@ class Agent(Base):
1213
1232
  """
1214
1233
  return dict_hash(self.to_dict(add_edsl_version=False))
1215
1234
 
1216
- def to_dict(self, add_edsl_version=True) -> dict[str, Union[dict, bool]]:
1235
+ def to_dict(self, add_edsl_version=True, full_dict=False) -> dict[str, Union[dict, bool]]:
1217
1236
  """Serialize to a dictionary with EDSL info.
1218
1237
 
1219
1238
  Example usage:
@@ -1230,11 +1249,11 @@ class Agent(Base):
1230
1249
  d["traits"] = copy.deepcopy(dict(self._traits))
1231
1250
  if self.name:
1232
1251
  d["name"] = self.name
1233
- if self.set_instructions:
1252
+ if self.set_instructions or full_dict:
1234
1253
  d["instruction"] = self.instruction
1235
- if self.set_traits_presentation_template:
1254
+ if self.set_traits_presentation_template or full_dict:
1236
1255
  d["traits_presentation_template"] = self.traits_presentation_template
1237
- if self.codebook:
1256
+ if self.codebook or full_dict:
1238
1257
  d["codebook"] = self.codebook
1239
1258
  if add_edsl_version:
1240
1259
  from edsl import __version__
@@ -47,13 +47,13 @@ class AgentList(UserList, Base, AgentListOperationsMixin):
47
47
  with methods for filtering, transforming, and analyzing collections of agents.
48
48
 
49
49
 
50
- >>> AgentList.example().to_scenario_list()
51
- ScenarioList([Scenario({'age': 22, 'hair': 'brown', 'height': 5.5}), Scenario({'age': 22, 'hair': 'brown', 'height': 5.5})])
52
-
50
+ >>> AgentList.example().to_scenario_list().drop('age')
51
+ ScenarioList([Scenario({'hair': 'brown', 'height': 5.5}), Scenario({'hair': 'brown', 'height': 5.5})])
52
+
53
53
  >>> AgentList.example().to_dataset()
54
54
  Dataset([{'age': [22, 22]}, {'hair': ['brown', 'brown']}, {'height': [5.5, 5.5]}])
55
55
 
56
- >>> AgentList.example().to_pandas()
56
+ >>> AgentList.example().select('age', 'hair', 'height').to_pandas()
57
57
  age hair height
58
58
  0 22 brown 5.5
59
59
  1 22 brown 5.5
@@ -91,6 +91,28 @@ class AgentList(UserList, Base, AgentListOperationsMixin):
91
91
  if codebook is not None:
92
92
  self.set_codebook(codebook)
93
93
 
94
+ def set_instruction(self, instruction: str) -> None:
95
+ """Set the instruction for all agents in the list.
96
+
97
+ Args:
98
+ instruction: The instruction to set.
99
+ """
100
+ for agent in self.data:
101
+ agent.instruction = instruction
102
+
103
+ return None
104
+
105
+ def set_traits_presentation_template(self, traits_presentation_template: str) -> None:
106
+ """Set the traits presentation template for all agents in the list.
107
+
108
+ Args:
109
+ traits_presentation_template: The traits presentation template to set.
110
+ """
111
+ for agent in self.data:
112
+ agent.traits_presentation_template = traits_presentation_template
113
+
114
+ return None
115
+
94
116
  def shuffle(self, seed: Optional[str] = None) -> AgentList:
95
117
  """Randomly shuffle the agents in place.
96
118
 
@@ -119,6 +141,14 @@ class AgentList(UserList, Base, AgentListOperationsMixin):
119
141
  if seed:
120
142
  random.seed(seed)
121
143
  return AgentList(random.sample(self.data, n))
144
+
145
+ def drop(self, field_name: str) -> AgentList:
146
+ """Drop a field from the AgentList.
147
+
148
+ Args:
149
+ field_name: The name of the field to drop.
150
+ """
151
+ return AgentList([a.drop(field_name) for a in self.data])
122
152
 
123
153
  def duplicate(self) -> AgentList:
124
154
  """Create a deep copy of the AgentList.
@@ -478,7 +508,7 @@ class AgentList(UserList, Base, AgentListOperationsMixin):
478
508
  >>> al.to_dataset()
479
509
  Dataset([{'age': [22, 22]}, {'hair': ['brown', 'brown']}, {'height': [5.5, 5.5]}])
480
510
  >>> al.to_dataset(traits_only=False) # doctest: +NORMALIZE_WHITESPACE
481
- Dataset([{'age': [22, 22]}, {'hair': ['brown', 'brown']}, {'height': [5.5, 5.5]}, {'agent_parameters': [{'instruction': 'You are answering questions as if you were a human. Do not break character.', 'agent_name': None}, {'instruction': 'You are answering questions as if you were a human. Do not break character.', 'agent_name': None}]}])
511
+ Dataset([{'age': [22, 22]}, {'hair': ['brown', 'brown']}, {'height': [5.5, 5.5]}, {'agent_parameters': [{'instruction': 'You are answering questions as if you were a human. Do not break character.', 'agent_name': None, 'traits_presentation_template': 'Your traits: {{traits}}'}, {'instruction': 'You are answering questions as if you were a human. Do not break character.', 'agent_name': None, 'traits_presentation_template': 'Your traits: {{traits}}'}]}])
482
512
  """
483
513
  from ..dataset import Dataset
484
514
 
@@ -495,7 +525,7 @@ class AgentList(UserList, Base, AgentListOperationsMixin):
495
525
  data[trait_key].append(agent.traits.get(trait_key, None))
496
526
  if not traits_only:
497
527
  data["agent_parameters"].append(
498
- {"instruction": agent.instruction, "agent_name": agent.name}
528
+ {"instruction": agent.instruction, "agent_name": agent.name, "traits_presentation_template": agent.traits_presentation_template}
499
529
  )
500
530
  return Dataset([{key: entry} for key, entry in data.items()])
501
531
 
@@ -17,6 +17,7 @@ class EDSLOutput(NamedTuple):
17
17
  answer: Any
18
18
  generated_tokens: str
19
19
  comment: Optional[str] = None
20
+ reasoning_summary: Optional[Any] = None
20
21
 
21
22
 
22
23
  class ModelResponse(NamedTuple):
@@ -49,6 +50,7 @@ class EDSLResultObjectInput(NamedTuple):
49
50
  cache_key: str
50
51
  answer: Any
51
52
  comment: str
53
+ reasoning_summary: Optional[Any] = None
52
54
  validated: bool = False
53
55
  exception_occurred: Exception = None
54
56
  input_tokens: Optional[int] = None
@@ -96,12 +98,15 @@ class Answers(UserDict):
96
98
  answer = response.answer
97
99
  comment = response.comment
98
100
  generated_tokens = response.generated_tokens
101
+ reasoning_summary = response.reasoning_summary
99
102
  # record the answer
100
103
  if generated_tokens:
101
104
  self[question.question_name + "_generated_tokens"] = generated_tokens
102
105
  self[question.question_name] = answer
103
106
  if comment:
104
107
  self[question.question_name + "_comment"] = comment
108
+ if reasoning_summary:
109
+ self[question.question_name + "_reasoning_summary"] = reasoning_summary
105
110
 
106
111
  def replace_missing_answers_with_none(self, survey: "Survey") -> None:
107
112
  """Replace missing answers with None. Answers can be missing if the agent skips a question."""
@@ -57,6 +57,7 @@ class InferenceServiceType(EnumWithChecks):
57
57
  DEEP_INFRA = "deep_infra"
58
58
  REPLICATE = "replicate"
59
59
  OPENAI = "openai"
60
+ OPENAI_V2 = "openai_v2"
60
61
  GOOGLE = "google"
61
62
  TEST = "test"
62
63
  ANTHROPIC = "anthropic"
@@ -77,6 +78,7 @@ InferenceServiceLiteral = Literal[
77
78
  "deep_infra",
78
79
  "replicate",
79
80
  "openai",
81
+ "openai_v2",
80
82
  "google",
81
83
  "test",
82
84
  "anthropic",
@@ -93,6 +95,7 @@ InferenceServiceLiteral = Literal[
93
95
  available_models_urls = {
94
96
  "anthropic": "https://docs.anthropic.com/en/docs/about-claude/models",
95
97
  "openai": "https://platform.openai.com/docs/models/gp",
98
+ "openai_v2": "https://platform.openai.com/docs/models/gp",
96
99
  "groq": "https://console.groq.com/docs/models",
97
100
  "google": "https://cloud.google.com/vertex-ai/generative-ai/docs/learn/models",
98
101
  }
@@ -102,6 +105,7 @@ service_to_api_keyname = {
102
105
  InferenceServiceType.DEEP_INFRA.value: "DEEP_INFRA_API_KEY",
103
106
  InferenceServiceType.REPLICATE.value: "TBD",
104
107
  InferenceServiceType.OPENAI.value: "OPENAI_API_KEY",
108
+ InferenceServiceType.OPENAI_V2.value: "OPENAI_API_KEY",
105
109
  InferenceServiceType.GOOGLE.value: "GOOGLE_API_KEY",
106
110
  InferenceServiceType.TEST.value: "TBD",
107
111
  InferenceServiceType.ANTHROPIC.value: "ANTHROPIC_API_KEY",
@@ -135,7 +139,7 @@ class TokenPricing:
135
139
  and self.prompt_token_price == other.prompt_token_price
136
140
  and self.completion_token_price == other.completion_token_price
137
141
  )
138
-
142
+
139
143
  @classmethod
140
144
  def example(cls) -> "TokenPricing":
141
145
  """Return an example TokenPricing object."""
@@ -145,6 +149,7 @@ class TokenPricing:
145
149
  completion_token_price_per_k=0.03,
146
150
  )
147
151
 
152
+
148
153
  pricing = {
149
154
  "dbrx-instruct": TokenPricing(
150
155
  model_name="dbrx-instruct",
@@ -212,4 +217,4 @@ def get_token_pricing(model_name):
212
217
  model_name=model_name,
213
218
  prompt_token_price_per_k=0.0,
214
219
  completion_token_price_per_k=0.0,
215
- )
220
+ )
@@ -2,6 +2,7 @@ import aiohttp
2
2
  import base64
3
3
  import json
4
4
  import requests
5
+ import time
5
6
 
6
7
  from typing import Any, Optional, Union, Literal, List, TypedDict, TYPE_CHECKING
7
8
  from uuid import UUID
@@ -13,7 +14,9 @@ from ..caching import CacheEntry
13
14
 
14
15
  if TYPE_CHECKING:
15
16
  from ..jobs import Jobs
17
+ from ..scenarios import ScenarioList
16
18
  from ..surveys import Survey
19
+ from ..results import Results
17
20
 
18
21
  from .exceptions import (
19
22
  CoopInvalidURLError,
@@ -567,6 +570,7 @@ class Coop(CoopFunctionsMixin):
567
570
  json.dumps(
568
571
  object_dict,
569
572
  default=self._json_handle_none,
573
+ allow_nan=False,
570
574
  )
571
575
  if object_type != "scenario"
572
576
  else ""
@@ -585,6 +589,7 @@ class Coop(CoopFunctionsMixin):
585
589
  json_data = json.dumps(
586
590
  object_dict,
587
591
  default=self._json_handle_none,
592
+ allow_nan=False,
588
593
  )
589
594
  headers = {"Content-Type": "application/json"}
590
595
  if response_json.get("upload_signed_url"):
@@ -928,6 +933,7 @@ class Coop(CoopFunctionsMixin):
928
933
  json.dumps(
929
934
  value.to_dict(),
930
935
  default=self._json_handle_none,
936
+ allow_nan=False,
931
937
  )
932
938
  if value
933
939
  else None
@@ -1385,12 +1391,108 @@ class Coop(CoopFunctionsMixin):
1385
1391
  self._resolve_server_response(response)
1386
1392
  response_json = response.json()
1387
1393
  return {
1388
- "name": response_json.get("project_name"),
1394
+ "project_name": response_json.get("project_name"),
1389
1395
  "uuid": response_json.get("uuid"),
1390
1396
  "admin_url": f"{self.url}/home/projects/{response_json.get('uuid')}",
1391
1397
  "respondent_url": f"{self.url}/respond/{response_json.get('uuid')}",
1392
1398
  }
1393
1399
 
1400
+ def get_project(
1401
+ self,
1402
+ project_uuid: str,
1403
+ ) -> dict:
1404
+ """
1405
+ Get a project from Coop.
1406
+ """
1407
+ response = self._send_server_request(
1408
+ uri=f"api/v0/projects/{project_uuid}",
1409
+ method="GET",
1410
+ )
1411
+ self._resolve_server_response(response)
1412
+ response_json = response.json()
1413
+ return {
1414
+ "project_name": response_json.get("project_name"),
1415
+ "project_job_uuids": response_json.get("job_uuids"),
1416
+ }
1417
+
1418
+ def get_project_human_responses(
1419
+ self,
1420
+ project_uuid: str,
1421
+ ) -> Union["Results", "ScenarioList"]:
1422
+ """
1423
+ Return a Results object with the human responses for a project.
1424
+
1425
+ If generating the Results object fails, a ScenarioList will be returned instead.
1426
+ """
1427
+ from ..agents import Agent, AgentList
1428
+ from ..caching import Cache
1429
+ from ..language_models import Model
1430
+ from ..scenarios import Scenario, ScenarioList
1431
+ from ..surveys import Survey
1432
+
1433
+ response = self._send_server_request(
1434
+ uri=f"api/v0/projects/{project_uuid}/human-responses",
1435
+ method="GET",
1436
+ )
1437
+ self._resolve_server_response(response)
1438
+ response_json = response.json()
1439
+ human_responses = response_json.get("human_responses", [])
1440
+
1441
+ try:
1442
+ agent_list = AgentList()
1443
+
1444
+ for response in human_responses:
1445
+ response_uuid = response.get("response_uuid")
1446
+ if response_uuid is None:
1447
+ raise RuntimeError(
1448
+ "One of your responses is missing a unique identifier."
1449
+ )
1450
+
1451
+ response_dict = json.loads(response.get("response_json_string"))
1452
+
1453
+ a = Agent(name=response_uuid, instruction="")
1454
+
1455
+ def create_answer_function(response_data):
1456
+ def f(self, question, scenario):
1457
+ return response_data.get(question.question_name, None)
1458
+
1459
+ return f
1460
+
1461
+ a.add_direct_question_answering_method(
1462
+ create_answer_function(response_dict)
1463
+ )
1464
+ agent_list.append(a)
1465
+
1466
+ survey_json_string = response_json.get("survey_json_string")
1467
+ survey = Survey.from_dict(json.loads(survey_json_string))
1468
+
1469
+ model = Model("test")
1470
+ results = (
1471
+ survey.by(agent_list)
1472
+ .by(model)
1473
+ .run(
1474
+ cache=Cache(),
1475
+ disable_remote_cache=True,
1476
+ disable_remote_inference=True,
1477
+ print_exceptions=False,
1478
+ )
1479
+ )
1480
+ return results
1481
+ except Exception:
1482
+ human_response_scenarios = []
1483
+ for response in human_responses:
1484
+ response_uuid = response.get("response_uuid")
1485
+ if response_uuid is None:
1486
+ raise RuntimeError(
1487
+ "One of your responses is missing a unique identifier."
1488
+ )
1489
+
1490
+ response_dict = json.loads(response.get("response_json_string"))
1491
+ response_dict["agent_name"] = response_uuid
1492
+ scenario = Scenario(response_dict)
1493
+ human_response_scenarios.append(scenario)
1494
+ return ScenarioList(human_response_scenarios)
1495
+
1394
1496
  def __repr__(self):
1395
1497
  """Return a string representation of the client."""
1396
1498
  return f"Client(api_key='{self.api_key}', url='{self.url}')"
@@ -93,6 +93,38 @@ class Dataset(UserList, DatasetOperationsMixin, PersistenceMixin, HashingMixin):
93
93
  """
94
94
  _, values = list(self.data[0].items())[0]
95
95
  return len(values)
96
+
97
+ def drop(self, field_name):
98
+ """
99
+ Returns a new Dataset with the specified field removed.
100
+
101
+ Args:
102
+ field_name (str): The name of the field to remove.
103
+
104
+ Returns:
105
+ Dataset: A new Dataset instance without the specified field.
106
+
107
+ Raises:
108
+ KeyError: If the field_name doesn't exist in the dataset.
109
+
110
+ Examples:
111
+ >>> from .dataset import Dataset
112
+ >>> d = Dataset([{'a': [1, 2, 3]}, {'b': [4, 5, 6]}])
113
+ >>> d.drop('a')
114
+ Dataset([{'b': [4, 5, 6]}])
115
+
116
+ >>> # Testing drop with nonexistent field raises DatasetKeyError - tested in unit tests
117
+ """
118
+ from .dataset import Dataset
119
+
120
+ # Check if field exists in the dataset
121
+ if field_name not in self.relevant_columns():
122
+ raise DatasetKeyError(f"Field '{field_name}' not found in dataset")
123
+
124
+ # Create a new dataset without the specified field
125
+ new_data = [entry for entry in self.data if field_name not in entry]
126
+ return Dataset(new_data)
127
+
96
128
 
97
129
  def tail(self, n: int = 5) -> Dataset:
98
130
  """Return the last n observations in the dataset.
@@ -1054,6 +1086,48 @@ class Dataset(UserList, DatasetOperationsMixin, PersistenceMixin, HashingMixin):
1054
1086
 
1055
1087
  return Dataset(new_data)
1056
1088
 
1089
+ def unique(self) -> "Dataset":
1090
+ """Return a new dataset with only unique observations.
1091
+
1092
+ Examples:
1093
+ >>> d = Dataset([{'a': [1, 2, 2, 3]}, {'b': [4, 5, 5, 6]}])
1094
+ >>> d.unique().data
1095
+ [{'a': [1, 2, 3]}, {'b': [4, 5, 6]}]
1096
+
1097
+ >>> d = Dataset([{'x': ['a', 'a', 'b']}, {'y': [1, 1, 2]}])
1098
+ >>> d.unique().data
1099
+ [{'x': ['a', 'b']}, {'y': [1, 2]}]
1100
+ """
1101
+ # Get all column names and values
1102
+ headers, data = self._tabular()
1103
+
1104
+ # Create a list of unique rows
1105
+ unique_rows = []
1106
+ seen = set()
1107
+
1108
+ for row in data:
1109
+ # Convert the row to a hashable representation for comparison
1110
+ # We need to handle potential unhashable types
1111
+ try:
1112
+ row_key = tuple(map(lambda x: str(x) if isinstance(x, (list, dict)) else x, row))
1113
+ if row_key not in seen:
1114
+ seen.add(row_key)
1115
+ unique_rows.append(row)
1116
+ except:
1117
+ # Fallback for complex objects: compare based on string representation
1118
+ row_str = str(row)
1119
+ if row_str not in seen:
1120
+ seen.add(row_str)
1121
+ unique_rows.append(row)
1122
+
1123
+ # Create a new dataset with unique combinations
1124
+ new_data = []
1125
+ for i, header in enumerate(headers):
1126
+ values = [row[i] for row in unique_rows]
1127
+ new_data.append({header: values})
1128
+
1129
+ return Dataset(new_data)
1130
+
1057
1131
 
1058
1132
  if __name__ == "__main__":
1059
1133
  import doctest