edsl 0.1.61__tar.gz → 0.1.62__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.61 → edsl-0.1.62}/PKG-INFO +1 -1
  2. edsl-0.1.62/edsl/__version__.py +1 -0
  3. {edsl-0.1.61 → edsl-0.1.62}/edsl/base/base_class.py +8 -0
  4. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/coop.py +263 -16
  5. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/coop_jobs_objects.py +2 -2
  6. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/coop_regular_objects.py +3 -1
  7. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/jobs.py +1 -1
  8. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/remote_inference.py +4 -4
  9. {edsl-0.1.61 → edsl-0.1.62}/edsl/prompts/prompt.py +7 -2
  10. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_registry.py +4 -1
  11. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/file_store.py +69 -0
  12. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/scenario.py +233 -0
  13. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/scenario_source.py +0 -1
  14. {edsl-0.1.61 → edsl-0.1.62}/pyproject.toml +1 -1
  15. edsl-0.1.61/edsl/__version__.py +0 -1
  16. {edsl-0.1.61 → edsl-0.1.62}/LICENSE +0 -0
  17. {edsl-0.1.61 → edsl-0.1.62}/README.md +0 -0
  18. {edsl-0.1.61 → edsl-0.1.62}/edsl/__init__.py +0 -0
  19. {edsl-0.1.61 → edsl-0.1.62}/edsl/__init__original.py +0 -0
  20. {edsl-0.1.61 → edsl-0.1.62}/edsl/agents/__init__.py +0 -0
  21. {edsl-0.1.61 → edsl-0.1.62}/edsl/agents/agent.py +0 -0
  22. {edsl-0.1.61 → edsl-0.1.62}/edsl/agents/agent_list.py +0 -0
  23. {edsl-0.1.61 → edsl-0.1.62}/edsl/agents/descriptors.py +0 -0
  24. {edsl-0.1.61 → edsl-0.1.62}/edsl/agents/exceptions.py +0 -0
  25. {edsl-0.1.61 → edsl-0.1.62}/edsl/base/__init__.py +0 -0
  26. {edsl-0.1.61 → edsl-0.1.62}/edsl/base/base_exception.py +0 -0
  27. {edsl-0.1.61 → edsl-0.1.62}/edsl/base/data_transfer_models.py +0 -0
  28. {edsl-0.1.61 → edsl-0.1.62}/edsl/base/enums.py +0 -0
  29. {edsl-0.1.61 → edsl-0.1.62}/edsl/base/exceptions.py +0 -0
  30. {edsl-0.1.61 → edsl-0.1.62}/edsl/base.py +0 -0
  31. {edsl-0.1.61 → edsl-0.1.62}/edsl/buckets/__init__.py +0 -0
  32. {edsl-0.1.61 → edsl-0.1.62}/edsl/buckets/bucket_collection.py +0 -0
  33. {edsl-0.1.61 → edsl-0.1.62}/edsl/buckets/exceptions.py +0 -0
  34. {edsl-0.1.61 → edsl-0.1.62}/edsl/buckets/model_buckets.py +0 -0
  35. {edsl-0.1.61 → edsl-0.1.62}/edsl/buckets/token_bucket.py +0 -0
  36. {edsl-0.1.61 → edsl-0.1.62}/edsl/buckets/token_bucket_api.py +0 -0
  37. {edsl-0.1.61 → edsl-0.1.62}/edsl/buckets/token_bucket_client.py +0 -0
  38. {edsl-0.1.61 → edsl-0.1.62}/edsl/caching/__init__.py +0 -0
  39. {edsl-0.1.61 → edsl-0.1.62}/edsl/caching/cache.py +0 -0
  40. {edsl-0.1.61 → edsl-0.1.62}/edsl/caching/cache_entry.py +0 -0
  41. {edsl-0.1.61 → edsl-0.1.62}/edsl/caching/cache_handler.py +0 -0
  42. {edsl-0.1.61 → edsl-0.1.62}/edsl/caching/exceptions.py +0 -0
  43. {edsl-0.1.61 → edsl-0.1.62}/edsl/caching/orm.py +0 -0
  44. {edsl-0.1.61 → edsl-0.1.62}/edsl/caching/remote_cache_sync.py +0 -0
  45. {edsl-0.1.61 → edsl-0.1.62}/edsl/caching/sql_dict.py +0 -0
  46. {edsl-0.1.61 → edsl-0.1.62}/edsl/cli.py +0 -0
  47. {edsl-0.1.61 → edsl-0.1.62}/edsl/config/__init__.py +0 -0
  48. {edsl-0.1.61 → edsl-0.1.62}/edsl/config/config_class.py +0 -0
  49. {edsl-0.1.61 → edsl-0.1.62}/edsl/config.py +0 -0
  50. {edsl-0.1.61 → edsl-0.1.62}/edsl/conversation/Conversation.py +0 -0
  51. {edsl-0.1.61 → edsl-0.1.62}/edsl/conversation/__init__.py +0 -0
  52. {edsl-0.1.61 → edsl-0.1.62}/edsl/conversation/car_buying.py +0 -0
  53. {edsl-0.1.61 → edsl-0.1.62}/edsl/conversation/chips.py +0 -0
  54. {edsl-0.1.61 → edsl-0.1.62}/edsl/conversation/exceptions.py +0 -0
  55. {edsl-0.1.61 → edsl-0.1.62}/edsl/conversation/mug_negotiation.py +0 -0
  56. {edsl-0.1.61 → edsl-0.1.62}/edsl/conversation/next_speaker_utilities.py +0 -0
  57. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/__init__.py +0 -0
  58. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/coop_functions.py +0 -0
  59. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/coop_objects.py +0 -0
  60. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/coop_prolific_filters.py +0 -0
  61. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/ep_key_handling.py +0 -0
  62. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/exceptions.py +0 -0
  63. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/price_fetcher.py +0 -0
  64. {edsl-0.1.61 → edsl-0.1.62}/edsl/coop/utils.py +0 -0
  65. {edsl-0.1.61 → edsl-0.1.62}/edsl/data_transfer_models.py +0 -0
  66. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/__init__.py +0 -0
  67. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/dataset.py +0 -0
  68. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/dataset_operations_mixin.py +0 -0
  69. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/dataset_tree.py +0 -0
  70. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/display/CSSParameterizer.py +0 -0
  71. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/display/__init__.py +0 -0
  72. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/display/table_data_class.py +0 -0
  73. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/display/table_display.css +0 -0
  74. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/display/table_display.py +0 -0
  75. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/display/table_renderers.py +0 -0
  76. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/exceptions.py +0 -0
  77. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/file_exports.py +0 -0
  78. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/r/ggplot.py +0 -0
  79. {edsl-0.1.61 → edsl-0.1.62}/edsl/dataset/tree_explore.py +0 -0
  80. {edsl-0.1.61 → edsl-0.1.62}/edsl/db_list/sqlite_list.py +0 -0
  81. {edsl-0.1.61 → edsl-0.1.62}/edsl/display/__init__.py +0 -0
  82. {edsl-0.1.61 → edsl-0.1.62}/edsl/display/core.py +0 -0
  83. {edsl-0.1.61 → edsl-0.1.62}/edsl/display/plugin.py +0 -0
  84. {edsl-0.1.61 → edsl-0.1.62}/edsl/display/utils.py +0 -0
  85. {edsl-0.1.61 → edsl-0.1.62}/edsl/enums.py +0 -0
  86. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/__init__.py +0 -0
  87. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/available_model_cache_handler.py +0 -0
  88. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/available_model_fetcher.py +0 -0
  89. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/data_structures.py +0 -0
  90. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/exceptions.py +0 -0
  91. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/inference_service_abc.py +0 -0
  92. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/inference_services_collection.py +0 -0
  93. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/models_available_cache.py +0 -0
  94. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/rate_limits_cache.py +0 -0
  95. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/registry.py +0 -0
  96. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/service_availability.py +0 -0
  97. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/__init__.py +0 -0
  98. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/anthropic_service.py +0 -0
  99. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/aws_bedrock.py +0 -0
  100. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/azure_ai.py +0 -0
  101. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/deep_infra_service.py +0 -0
  102. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/deep_seek_service.py +0 -0
  103. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/google_service.py +0 -0
  104. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/groq_service.py +0 -0
  105. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/mistral_ai_service.py +0 -0
  106. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/ollama_service.py +0 -0
  107. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/open_ai_service.py +0 -0
  108. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/open_ai_service_v2.py +0 -0
  109. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/perplexity_service.py +0 -0
  110. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/test_service.py +0 -0
  111. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/together_ai_service.py +0 -0
  112. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/services/xai_service.py +0 -0
  113. {edsl-0.1.61 → edsl-0.1.62}/edsl/inference_services/write_available.py +0 -0
  114. {edsl-0.1.61 → edsl-0.1.62}/edsl/instructions/__init__.py +0 -0
  115. {edsl-0.1.61 → edsl-0.1.62}/edsl/instructions/change_instruction.py +0 -0
  116. {edsl-0.1.61 → edsl-0.1.62}/edsl/instructions/exceptions.py +0 -0
  117. {edsl-0.1.61 → edsl-0.1.62}/edsl/instructions/instruction.py +0 -0
  118. {edsl-0.1.61 → edsl-0.1.62}/edsl/instructions/instruction_collection.py +0 -0
  119. {edsl-0.1.61 → edsl-0.1.62}/edsl/instructions/instruction_handler.py +0 -0
  120. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/ReportErrors.py +0 -0
  121. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/__init__.py +0 -0
  122. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/answering_function.py +0 -0
  123. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/exception_tracking.py +0 -0
  124. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/exceptions.py +0 -0
  125. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/interview.py +0 -0
  126. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/interview_status_dictionary.py +0 -0
  127. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/interview_status_enum.py +0 -0
  128. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/interview_status_log.py +0 -0
  129. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/interview_task_manager.py +0 -0
  130. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/request_token_estimator.py +0 -0
  131. {edsl-0.1.61 → edsl-0.1.62}/edsl/interviews/statistics.py +0 -0
  132. {edsl-0.1.61 → edsl-0.1.62}/edsl/invigilators/__init__.py +0 -0
  133. {edsl-0.1.61 → edsl-0.1.62}/edsl/invigilators/exceptions.py +0 -0
  134. {edsl-0.1.61 → edsl-0.1.62}/edsl/invigilators/invigilator_base.py +0 -0
  135. {edsl-0.1.61 → edsl-0.1.62}/edsl/invigilators/invigilators.py +0 -0
  136. {edsl-0.1.61 → edsl-0.1.62}/edsl/invigilators/prompt_constructor.py +0 -0
  137. {edsl-0.1.61 → edsl-0.1.62}/edsl/invigilators/prompt_helpers.py +0 -0
  138. {edsl-0.1.61 → edsl-0.1.62}/edsl/invigilators/question_instructions_prompt_builder.py +0 -0
  139. {edsl-0.1.61 → edsl-0.1.62}/edsl/invigilators/question_option_processor.py +0 -0
  140. {edsl-0.1.61 → edsl-0.1.62}/edsl/invigilators/question_template_replacements_builder.py +0 -0
  141. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/__init__.py +0 -0
  142. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/async_interview_runner.py +0 -0
  143. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/check_survey_scenario_compatibility.py +0 -0
  144. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/data_structures.py +0 -0
  145. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/decorators.py +0 -0
  146. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/exceptions.py +0 -0
  147. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/fetch_invigilator.py +0 -0
  148. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/html_table_job_logger.py +0 -0
  149. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/jobs_checks.py +0 -0
  150. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/jobs_component_constructor.py +0 -0
  151. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/jobs_interview_constructor.py +0 -0
  152. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/jobs_pricing_estimation.py +0 -0
  153. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/jobs_remote_inference_logger.py +0 -0
  154. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/jobs_runner_status.py +0 -0
  155. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/jobs_status_enums.py +0 -0
  156. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/progress_bar_manager.py +0 -0
  157. {edsl-0.1.61 → edsl-0.1.62}/edsl/jobs/results_exceptions_handler.py +0 -0
  158. {edsl-0.1.61 → edsl-0.1.62}/edsl/key_management/__init__.py +0 -0
  159. {edsl-0.1.61 → edsl-0.1.62}/edsl/key_management/exceptions.py +0 -0
  160. {edsl-0.1.61 → edsl-0.1.62}/edsl/key_management/key_lookup.py +0 -0
  161. {edsl-0.1.61 → edsl-0.1.62}/edsl/key_management/key_lookup_builder.py +0 -0
  162. {edsl-0.1.61 → edsl-0.1.62}/edsl/key_management/key_lookup_collection.py +0 -0
  163. {edsl-0.1.61 → edsl-0.1.62}/edsl/key_management/models.py +0 -0
  164. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/__init__.py +0 -0
  165. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/exceptions.py +0 -0
  166. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/language_model.py +0 -0
  167. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/model.py +0 -0
  168. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/model_list.py +0 -0
  169. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/price_manager.py +0 -0
  170. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/raw_response_handler.py +0 -0
  171. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/registry.py +0 -0
  172. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/repair.py +0 -0
  173. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/unused/fake_openai_call.py +0 -0
  174. {edsl-0.1.61 → edsl-0.1.62}/edsl/language_models/utilities.py +0 -0
  175. {edsl-0.1.61 → edsl-0.1.62}/edsl/load_plugins.py +0 -0
  176. {edsl-0.1.61 → edsl-0.1.62}/edsl/logger.py +0 -0
  177. {edsl-0.1.61 → edsl-0.1.62}/edsl/notebooks/__init__.py +0 -0
  178. {edsl-0.1.61 → edsl-0.1.62}/edsl/notebooks/exceptions.py +0 -0
  179. {edsl-0.1.61 → edsl-0.1.62}/edsl/notebooks/notebook.py +0 -0
  180. {edsl-0.1.61 → edsl-0.1.62}/edsl/notebooks/notebook_to_latex.py +0 -0
  181. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/__init__.py +0 -0
  182. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/built_in/export_example.py +0 -0
  183. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/built_in/pig_latin.py +0 -0
  184. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/cli.py +0 -0
  185. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/cli_typer.py +0 -0
  186. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/exceptions.py +0 -0
  187. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/hookspec.py +0 -0
  188. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/plugin_host.py +0 -0
  189. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/plugin_manager.py +0 -0
  190. {edsl-0.1.61 → edsl-0.1.62}/edsl/plugins/plugins_registry.py +0 -0
  191. {edsl-0.1.61 → edsl-0.1.62}/edsl/prompts/__init__.py +0 -0
  192. {edsl-0.1.61 → edsl-0.1.62}/edsl/prompts/exceptions.py +0 -0
  193. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/ExceptionExplainer.py +0 -0
  194. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/HTMLQuestion.py +0 -0
  195. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/Quick.py +0 -0
  196. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/VALIDATION_README.md +0 -0
  197. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/__init__.py +0 -0
  198. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/answer_validator_mixin.py +0 -0
  199. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/compose_questions.py +0 -0
  200. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/data_structures.py +0 -0
  201. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/decorators.py +0 -0
  202. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/descriptors.py +0 -0
  203. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/exceptions.py +0 -0
  204. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/loop_processor.py +0 -0
  205. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/prompt_templates/question_budget.jinja +0 -0
  206. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/prompt_templates/question_checkbox.jinja +0 -0
  207. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/prompt_templates/question_extract.jinja +0 -0
  208. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/prompt_templates/question_free_text.jinja +0 -0
  209. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/prompt_templates/question_linear_scale.jinja +0 -0
  210. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/prompt_templates/question_list.jinja +0 -0
  211. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/prompt_templates/question_multiple_choice.jinja +0 -0
  212. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/prompt_templates/question_numerical.jinja +0 -0
  213. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_base.py +0 -0
  214. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_base_gen_mixin.py +0 -0
  215. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_base_prompts_mixin.py +0 -0
  216. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_budget.py +0 -0
  217. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_check_box.py +0 -0
  218. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_dict.py +0 -0
  219. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_extract.py +0 -0
  220. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_free_text.py +0 -0
  221. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_functional.py +0 -0
  222. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_likert_five.py +0 -0
  223. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_linear_scale.py +0 -0
  224. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_list.py +0 -0
  225. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_matrix.py +0 -0
  226. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_multiple_choice.py +0 -0
  227. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_multiple_choice_with_other.py +0 -0
  228. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_numerical.py +0 -0
  229. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_rank.py +0 -0
  230. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_top_k.py +0 -0
  231. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/question_yes_no.py +0 -0
  232. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/register_questions_meta.py +0 -0
  233. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/response_validator_abc.py +0 -0
  234. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/response_validator_factory.py +0 -0
  235. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/settings.py +0 -0
  236. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/simple_ask_mixin.py +0 -0
  237. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/__init__.py +0 -0
  238. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/budget/__init__.py +0 -0
  239. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/budget/answering_instructions.jinja +0 -0
  240. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/budget/question_presentation.jinja +0 -0
  241. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/checkbox/__init__.py +0 -0
  242. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/checkbox/answering_instructions.jinja +0 -0
  243. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/checkbox/question_presentation.jinja +0 -0
  244. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/dict/__init__.py +0 -0
  245. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/dict/answering_instructions.jinja +0 -0
  246. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/dict/question_presentation.jinja +0 -0
  247. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/extract/__init__.py +0 -0
  248. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/extract/answering_instructions.jinja +0 -0
  249. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/extract/question_presentation.jinja +0 -0
  250. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/free_text/__init__.py +0 -0
  251. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/free_text/answering_instructions.jinja +0 -0
  252. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/free_text/question_presentation.jinja +0 -0
  253. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/likert_five/__init__.py +0 -0
  254. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/likert_five/answering_instructions.jinja +0 -0
  255. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/likert_five/question_presentation.jinja +0 -0
  256. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/linear_scale/__init__.py +0 -0
  257. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/linear_scale/answering_instructions.jinja +0 -0
  258. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/linear_scale/question_presentation.jinja +0 -0
  259. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/list/__init__.py +0 -0
  260. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/list/answering_instructions.jinja +0 -0
  261. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/list/question_presentation.jinja +0 -0
  262. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/matrix/__init__.py +0 -0
  263. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/matrix/answering_instructions.jinja +0 -0
  264. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/matrix/question_presentation.jinja +0 -0
  265. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/multiple_choice/__init__.py +0 -0
  266. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/multiple_choice/answering_instructions.jinja +0 -0
  267. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/multiple_choice/html.jinja +0 -0
  268. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/multiple_choice/question_presentation.jinja +0 -0
  269. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/multiple_choice_with_other/__init__.py +0 -0
  270. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/multiple_choice_with_other/answering_instructions.jinja +0 -0
  271. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/multiple_choice_with_other/question_presentation.jinja +0 -0
  272. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/numerical/__init__.py +0 -0
  273. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/numerical/answering_instructions.jinja +0 -0
  274. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/numerical/question_presentation.jinja +0 -0
  275. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/rank/__init__.py +0 -0
  276. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/rank/answering_instructions.jinja +0 -0
  277. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/rank/question_presentation.jinja +0 -0
  278. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/top_k/__init__.py +0 -0
  279. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/top_k/answering_instructions.jinja +0 -0
  280. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/top_k/question_presentation.jinja +0 -0
  281. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/yes_no/__init__.py +0 -0
  282. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/yes_no/answering_instructions.jinja +0 -0
  283. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/templates/yes_no/question_presentation.jinja +0 -0
  284. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/validation_analysis.py +0 -0
  285. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/validation_cli.py +0 -0
  286. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/validation_html_report.py +0 -0
  287. {edsl-0.1.61 → edsl-0.1.62}/edsl/questions/validation_logger.py +0 -0
  288. {edsl-0.1.61 → edsl-0.1.62}/edsl/results/__init__.py +0 -0
  289. {edsl-0.1.61 → edsl-0.1.62}/edsl/results/exceptions.py +0 -0
  290. {edsl-0.1.61 → edsl-0.1.62}/edsl/results/report.py +0 -0
  291. {edsl-0.1.61 → edsl-0.1.62}/edsl/results/result.py +0 -0
  292. {edsl-0.1.61 → edsl-0.1.62}/edsl/results/results.py +0 -0
  293. {edsl-0.1.61 → edsl-0.1.62}/edsl/results/results_selector.py +0 -0
  294. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/DocxScenario.py +0 -0
  295. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/PdfExtractor.py +0 -0
  296. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/__init__.py +0 -0
  297. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/construct_download_link.py +0 -0
  298. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/directory_scanner.py +0 -0
  299. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/document_chunker.py +0 -0
  300. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/exceptions.py +0 -0
  301. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/file_methods.py +0 -0
  302. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/__init__.py +0 -0
  303. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/csv_file_store.py +0 -0
  304. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/docx_file_store.py +0 -0
  305. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/html_file_store.py +0 -0
  306. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/jpeg_file_store.py +0 -0
  307. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/json_file_store.py +0 -0
  308. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/latex_file_store.py +0 -0
  309. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/md_file_store.py +0 -0
  310. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/mp4_file_store.py +0 -0
  311. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/pdf_file_store.py +0 -0
  312. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/png_file_store.py +0 -0
  313. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/pptx_file_store.py +0 -0
  314. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/py_file_store.py +0 -0
  315. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/sql_file_store.py +0 -0
  316. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/sqlite_file_store.py +0 -0
  317. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/txt_file_store.py +0 -0
  318. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/handlers/webm_file_store.py +0 -0
  319. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/scenario_join.py +0 -0
  320. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/scenario_list.py +0 -0
  321. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/scenario_list_gc_test.py +0 -0
  322. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/scenario_list_memory_test.py +0 -0
  323. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/scenario_list_pdf_tools.py +0 -0
  324. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/scenario_list_source_refactor.md +0 -0
  325. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/scenario_selector.py +0 -0
  326. {edsl-0.1.61 → edsl-0.1.62}/edsl/scenarios/tests/test_scenario_list_sources.py +0 -0
  327. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/__init__.py +0 -0
  328. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/base.py +0 -0
  329. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/dag/__init__.py +0 -0
  330. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/dag/construct_dag.py +0 -0
  331. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/dag/dag.py +0 -0
  332. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/descriptors.py +0 -0
  333. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/edit_survey.py +0 -0
  334. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/exceptions.py +0 -0
  335. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/memory/__init__.py +0 -0
  336. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/memory/memory.py +0 -0
  337. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/memory/memory_management.py +0 -0
  338. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/memory/memory_plan.py +0 -0
  339. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/rules/__init__.py +0 -0
  340. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/rules/rule.py +0 -0
  341. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/rules/rule_collection.py +0 -0
  342. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/rules/rule_manager.py +0 -0
  343. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/survey.py +0 -0
  344. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/survey_css.py +0 -0
  345. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/survey_export.py +0 -0
  346. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/survey_flow_visualization.py +0 -0
  347. {edsl-0.1.61 → edsl-0.1.62}/edsl/surveys/survey_simulator.py +0 -0
  348. {edsl-0.1.61 → edsl-0.1.62}/edsl/tasks/__init__.py +0 -0
  349. {edsl-0.1.61 → edsl-0.1.62}/edsl/tasks/exceptions.py +0 -0
  350. {edsl-0.1.61 → edsl-0.1.62}/edsl/tasks/question_task_creator.py +0 -0
  351. {edsl-0.1.61 → edsl-0.1.62}/edsl/tasks/task_creators.py +0 -0
  352. {edsl-0.1.61 → edsl-0.1.62}/edsl/tasks/task_history.py +0 -0
  353. {edsl-0.1.61 → edsl-0.1.62}/edsl/tasks/task_status_enum.py +0 -0
  354. {edsl-0.1.61 → edsl-0.1.62}/edsl/tasks/task_status_log.py +0 -0
  355. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/base.html +0 -0
  356. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/exceptions_by_model.html +0 -0
  357. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/exceptions_by_question_name.html +0 -0
  358. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/exceptions_by_type.html +0 -0
  359. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/exceptions_table.html +0 -0
  360. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/interview_details.html +0 -0
  361. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/interviews.html +0 -0
  362. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/overview.html +0 -0
  363. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/performance_plot.html +0 -0
  364. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/report.css +0 -0
  365. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/report.html +0 -0
  366. {edsl-0.1.61 → edsl-0.1.62}/edsl/templates/error_reporting/report.js +0 -0
  367. {edsl-0.1.61 → edsl-0.1.62}/edsl/tests/scenarios/test_ScenarioSource.py +0 -0
  368. {edsl-0.1.61 → edsl-0.1.62}/edsl/tests/scenarios/test_scenario_list_sources.py +0 -0
  369. {edsl-0.1.61 → edsl-0.1.62}/edsl/tokens/__init__.py +0 -0
  370. {edsl-0.1.61 → edsl-0.1.62}/edsl/tokens/exceptions.py +0 -0
  371. {edsl-0.1.61 → edsl-0.1.62}/edsl/tokens/interview_token_usage.py +0 -0
  372. {edsl-0.1.61 → edsl-0.1.62}/edsl/tokens/token_usage.py +0 -0
  373. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/PrettyList.py +0 -0
  374. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/SystemInfo.py +0 -0
  375. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/__init__.py +0 -0
  376. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/ast_utilities.py +0 -0
  377. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/decorators.py +0 -0
  378. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/gcp_bucket/__init__.py +0 -0
  379. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/gcp_bucket/cloud_storage.py +0 -0
  380. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/is_notebook.py +0 -0
  381. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/is_valid_variable_name.py +0 -0
  382. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/markdown_to_docx.py +0 -0
  383. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/markdown_to_pdf.py +0 -0
  384. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/memory_debugger.py +0 -0
  385. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/naming_utilities.py +0 -0
  386. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/remove_edsl_version.py +0 -0
  387. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/repair_functions.py +0 -0
  388. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/restricted_python.py +0 -0
  389. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/template_loader.py +0 -0
  390. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/utilities.py +0 -0
  391. {edsl-0.1.61 → edsl-0.1.62}/edsl/utilities/wikipedia.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.61
3
+ Version: 0.1.62
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
@@ -0,0 +1 @@
1
+ __version__ = "0.1.62"
@@ -331,9 +331,17 @@ class PersistenceMixin:
331
331
  """
332
332
  from edsl.coop import Coop
333
333
  from edsl.coop import ObjectRegistry
334
+ from edsl.jobs import Jobs
334
335
 
335
336
  coop = Coop(url=expected_parrot_url)
336
337
 
338
+ if issubclass(cls, Jobs):
339
+ job_data = coop.new_remote_inference_get(
340
+ str(url_or_uuid), include_json_string=True
341
+ )
342
+ job_dict = json.loads(job_data.get("job_json_string"))
343
+ return cls.from_dict(job_dict)
344
+
337
345
  object_type = ObjectRegistry.get_object_type_by_edsl_class(cls)
338
346
 
339
347
  return coop.pull(url_or_uuid, object_type)
@@ -598,7 +598,7 @@ class Coop(CoopFunctionsMixin):
598
598
  else:
599
599
  from .exceptions import CoopResponseError
600
600
 
601
- raise CoopResponseError("No signed url was provided received")
601
+ raise CoopResponseError("No signed url was provided.")
602
602
 
603
603
  response = requests.put(
604
604
  signed_url, data=json_data.encode(), headers=headers
@@ -945,18 +945,31 @@ class Coop(CoopFunctionsMixin):
945
945
 
946
946
  obj_uuid, owner_username, obj_alias = self._resolve_uuid_or_alias(url_or_uuid)
947
947
 
948
- # If we have a UUID and are updating the value, check the storage format first
949
- if obj_uuid and value:
950
- # Check if object is in new format (GCS)
951
- format_check_response = self._send_server_request(
952
- uri="api/v0/object/check-format",
953
- method="POST",
954
- payload={"object_uuid": str(obj_uuid)},
955
- )
956
- self._resolve_server_response(format_check_response)
957
- format_data = format_check_response.json()
948
+ # If we're updating the value, we need to check the storage format
949
+ if value:
950
+ # If we don't have a UUID but have an alias, get the UUID and format info first
951
+ if not obj_uuid and owner_username and obj_alias:
952
+ # Get object info including UUID and format
953
+ info_response = self._send_server_request(
954
+ uri="api/v0/object/alias/info",
955
+ method="GET",
956
+ params={"owner_username": owner_username, "alias": obj_alias},
957
+ )
958
+ self._resolve_server_response(info_response)
959
+ info_data = info_response.json()
958
960
 
959
- is_new_format = format_data.get("is_new_format", False)
961
+ obj_uuid = info_data.get("uuid")
962
+ is_new_format = info_data.get("is_new_format", False)
963
+ else:
964
+ # We have a UUID, check the format
965
+ format_check_response = self._send_server_request(
966
+ uri="api/v0/object/check-format",
967
+ method="POST",
968
+ payload={"object_uuid": str(obj_uuid)},
969
+ )
970
+ self._resolve_server_response(format_check_response)
971
+ format_data = format_check_response.json()
972
+ is_new_format = format_data.get("is_new_format", False)
960
973
 
961
974
  if is_new_format:
962
975
  # Handle new format objects: update metadata first, then upload content
@@ -1052,10 +1065,20 @@ class Coop(CoopFunctionsMixin):
1052
1065
  f"Failed to upload object to GCS: {gcs_response.status_code}"
1053
1066
  )
1054
1067
 
1068
+ # Step 4: Confirm upload and trigger queue worker processing
1069
+ confirm_response = self._send_server_request(
1070
+ uri="api/v0/object/confirm-upload",
1071
+ method="POST",
1072
+ payload={"object_uuid": str(obj_uuid)},
1073
+ )
1074
+ self._resolve_server_response(confirm_response)
1075
+ confirm_data = confirm_response.json()
1076
+
1055
1077
  return {
1056
1078
  "status": "success",
1057
- "message": "Object updated successfully (new format - uploaded to GCS)",
1079
+ "message": "Object updated successfully (new format - uploaded to GCS and processing triggered)",
1058
1080
  "object_uuid": str(obj_uuid),
1081
+ "processing_started": confirm_data.get("processing_started", False),
1059
1082
  }
1060
1083
 
1061
1084
  ################
@@ -1195,7 +1218,7 @@ class Coop(CoopFunctionsMixin):
1195
1218
  if not upload_signed_url:
1196
1219
  from .exceptions import CoopResponseError
1197
1220
 
1198
- raise CoopResponseError("No signed url was provided received")
1221
+ raise CoopResponseError("No signed url was provided.")
1199
1222
 
1200
1223
  response = requests.put(
1201
1224
  upload_signed_url,
@@ -1431,6 +1454,160 @@ class Coop(CoopFunctionsMixin):
1431
1454
  }
1432
1455
  )
1433
1456
 
1457
+ def new_remote_inference_get(
1458
+ self,
1459
+ job_uuid: Optional[str] = None,
1460
+ results_uuid: Optional[str] = None,
1461
+ include_json_string: Optional[bool] = False,
1462
+ ) -> RemoteInferenceResponse:
1463
+ """
1464
+ Get the status and details of a remote inference job.
1465
+
1466
+ This method retrieves the current status and information about a remote job,
1467
+ including links to results if the job has completed successfully.
1468
+
1469
+ Parameters:
1470
+ job_uuid (str, optional): The UUID of the remote job to check
1471
+ results_uuid (str, optional): The UUID of the results associated with the job
1472
+ (can be used if you only have the results UUID)
1473
+ include_json_string (bool, optional): If True, include the json string for the job in the response
1474
+
1475
+ Returns:
1476
+ RemoteInferenceResponse: Information about the job including:
1477
+ job_uuid: The unique identifier for the job
1478
+ results_uuid: The UUID of the results
1479
+ results_url: URL to access the results
1480
+ status: Current status ("queued", "running", "completed", "failed")
1481
+ version: EDSL version used for the job
1482
+ job_json_string: The json string for the job (if include_json_string is True)
1483
+ latest_job_run_details: Metadata about the job status
1484
+ interview_details: Metadata about the job interview status (for jobs that have reached running status)
1485
+ total_interviews: The total number of interviews in the job
1486
+ completed_interviews: The number of completed interviews
1487
+ interviews_with_exceptions: The number of completed interviews that have exceptions
1488
+ exception_counters: A list of exception counts for the job
1489
+ exception_type: The type of exception
1490
+ inference_service: The inference service
1491
+ model: The model
1492
+ question_name: The name of the question
1493
+ exception_count: The number of exceptions
1494
+ failure_reason: The reason the job failed (failed jobs only)
1495
+ failure_description: The description of the failure (failed jobs only)
1496
+ error_report_uuid: The UUID of the error report (partially failed jobs only)
1497
+ cost_credits: The cost of the job run in credits
1498
+ cost_usd: The cost of the job run in USD
1499
+ expenses: The expenses incurred by the job run
1500
+ service: The service
1501
+ model: The model
1502
+ token_type: The type of token (input or output)
1503
+ price_per_million_tokens: The price per million tokens
1504
+ tokens_count: The number of tokens consumed
1505
+ cost_credits: The cost of the service/model/token type combination in credits
1506
+ cost_usd: The cost of the service/model/token type combination in USD
1507
+
1508
+ Raises:
1509
+ ValueError: If neither job_uuid nor results_uuid is provided
1510
+ CoopServerResponseError: If there's an error communicating with the server
1511
+
1512
+ Notes:
1513
+ - Either job_uuid or results_uuid must be provided
1514
+ - If both are provided, job_uuid takes precedence
1515
+ - For completed jobs, you can use the results_url to view or download results
1516
+ - For failed jobs, check the latest_error_report_url for debugging information
1517
+
1518
+ Example:
1519
+ >>> job_status = coop.new_remote_inference_get("9f8484ee-b407-40e4-9652-4133a7236c9c")
1520
+ >>> print(f"Job status: {job_status['status']}")
1521
+ >>> if job_status['status'] == 'completed':
1522
+ ... print(f"Results available at: {job_status['results_url']}")
1523
+ """
1524
+ if job_uuid is None and results_uuid is None:
1525
+ from .exceptions import CoopValueError
1526
+
1527
+ raise CoopValueError("Either job_uuid or results_uuid must be provided.")
1528
+ elif job_uuid is not None:
1529
+ params = {"job_uuid": job_uuid}
1530
+ else:
1531
+ params = {"results_uuid": results_uuid}
1532
+ if include_json_string:
1533
+ params["include_json_string"] = include_json_string
1534
+
1535
+ response = self._send_server_request(
1536
+ uri="api/v0/remote-inference",
1537
+ method="GET",
1538
+ params=params,
1539
+ )
1540
+ self._resolve_server_response(response)
1541
+ data = response.json()
1542
+
1543
+ results_uuid = data.get("results_uuid")
1544
+
1545
+ if results_uuid is None:
1546
+ results_url = None
1547
+ else:
1548
+ results_url = f"{self.url}/content/{results_uuid}"
1549
+
1550
+ latest_job_run_details = data.get("latest_job_run_details", {})
1551
+ if data.get("status") == "partial_failed":
1552
+ latest_error_report_uuid = latest_job_run_details.get("error_report_uuid")
1553
+ if latest_error_report_uuid is None:
1554
+ latest_job_run_details["error_report_url"] = None
1555
+ else:
1556
+ latest_error_report_url = (
1557
+ f"{self.url}/home/remote-inference/error/{latest_error_report_uuid}"
1558
+ )
1559
+ latest_job_run_details["error_report_url"] = latest_error_report_url
1560
+
1561
+ json_string = data.get("job_json_string")
1562
+
1563
+ # The job has been offloaded to GCS
1564
+ if include_json_string and json_string == "offloaded":
1565
+
1566
+ # Attempt to fetch JSON string from GCS
1567
+ response = self._send_server_request(
1568
+ uri="api/v0/remote-inference/pull",
1569
+ method="POST",
1570
+ payload={"job_uuid": job_uuid},
1571
+ )
1572
+ # Handle any errors in the response
1573
+ self._resolve_server_response(response)
1574
+ if "signed_url" not in response.json():
1575
+ from .exceptions import CoopResponseError
1576
+
1577
+ raise CoopResponseError("No signed url was provided.")
1578
+ signed_url = response.json().get("signed_url")
1579
+
1580
+ if signed_url == "": # The job is in legacy format
1581
+ job_json = json_string
1582
+
1583
+ try:
1584
+ response = requests.get(signed_url)
1585
+ self._resolve_gcs_response(response)
1586
+ job_json = json.dumps(response.json())
1587
+ except Exception:
1588
+ job_json = json_string
1589
+
1590
+ # If the job is in legacy format, we should already have the JSON string
1591
+ # from the first API call
1592
+ elif include_json_string and not json_string == "offloaded":
1593
+ job_json = json_string
1594
+
1595
+ # If include_json_string is False, we don't need the JSON string at all
1596
+ else:
1597
+ job_json = None
1598
+
1599
+ return RemoteInferenceResponse(
1600
+ **{
1601
+ "job_uuid": data.get("job_uuid"),
1602
+ "results_uuid": results_uuid,
1603
+ "results_url": results_url,
1604
+ "status": data.get("status"),
1605
+ "version": data.get("version"),
1606
+ "job_json_string": job_json,
1607
+ "latest_job_run_details": latest_job_run_details,
1608
+ }
1609
+ )
1610
+
1434
1611
  def _validate_remote_job_status_types(
1435
1612
  self, status: Union[RemoteJobStatus, List[RemoteJobStatus]]
1436
1613
  ) -> List[RemoteJobStatus]:
@@ -2470,7 +2647,7 @@ class Coop(CoopFunctionsMixin):
2470
2647
  if "signed_url" not in response.json():
2471
2648
  from .exceptions import CoopResponseError
2472
2649
 
2473
- raise CoopResponseError("No signed url was provided received")
2650
+ raise CoopResponseError("No signed url was provided.")
2474
2651
  signed_url = response.json().get("signed_url")
2475
2652
 
2476
2653
  if signed_url == "": # it is in old format
@@ -2872,6 +3049,53 @@ class Coop(CoopFunctionsMixin):
2872
3049
  self._resolve_server_response(response)
2873
3050
  return response.json()
2874
3051
 
3052
+ def pay_for_service(
3053
+ self,
3054
+ credits_transferred: int,
3055
+ recipient_username: str,
3056
+ service_name: str,
3057
+ ) -> dict:
3058
+ """
3059
+ Pay for a service.
3060
+
3061
+ This method transfers a specified number of credits from the authenticated user's
3062
+ account to another user's account on the Expected Parrot platform.
3063
+
3064
+ Parameters:
3065
+ credits_transferred (int): The number of credits to transfer to the recipient
3066
+ recipient_username (str): The username of the recipient
3067
+ service_name (str): The name of the service to pay for
3068
+
3069
+ Returns:
3070
+ dict: Information about the transfer transaction, including:
3071
+ - success: Whether the transaction was successful
3072
+ - transaction_id: A unique identifier for the transaction
3073
+ - remaining_credits: The number of credits remaining in the sender's account
3074
+
3075
+ Raises:
3076
+ CoopServerResponseError: If there's an error communicating with the server
3077
+ or if the transfer criteria aren't met (e.g., insufficient credits)
3078
+
3079
+ Example:
3080
+ >>> result = coop.pay_for_service(
3081
+ ... credits_transferred=100,
3082
+ ... service_name="service_name",
3083
+ ... recipient_username="friend_username",
3084
+ ... )
3085
+ >>> print(f"Transfer successful! You have {result['remaining_credits']} credits left.")
3086
+ """
3087
+ response = self._send_server_request(
3088
+ uri="api/v0/users/pay-for-service",
3089
+ method="POST",
3090
+ payload={
3091
+ "cost_credits": credits_transferred,
3092
+ "service_name": service_name,
3093
+ "recipient_username": recipient_username,
3094
+ },
3095
+ )
3096
+ self._resolve_server_response(response)
3097
+ return response.json()
3098
+
2875
3099
  def get_balance(self) -> dict:
2876
3100
  """
2877
3101
  Get the current credit balance for the authenticated user.
@@ -2897,6 +3121,29 @@ class Coop(CoopFunctionsMixin):
2897
3121
  self._resolve_server_response(response)
2898
3122
  return response.json()
2899
3123
 
3124
+ def get_profile(self) -> dict:
3125
+ """
3126
+ Get the current user's profile information.
3127
+
3128
+ This method retrieves the authenticated user's profile information from
3129
+ the Expected Parrot platform using their API key.
3130
+
3131
+ Returns:
3132
+ dict: User profile information including:
3133
+ - username: The user's username
3134
+ - email: The user's email address
3135
+
3136
+ Raises:
3137
+ CoopServerResponseError: If there's an error communicating with the server
3138
+
3139
+ Example:
3140
+ >>> profile = coop.get_profile()
3141
+ >>> print(f"Welcome, {profile['username']}!")
3142
+ """
3143
+ response = self._send_server_request(uri="api/v0/users/profile", method="GET")
3144
+ self._resolve_server_response(response)
3145
+ return response.json()
3146
+
2900
3147
  def login_gradio(self, timeout: int = 120, launch: bool = True, **launch_kwargs):
2901
3148
  """
2902
3149
  Start the EDSL auth token login flow inside a **Gradio** application.
@@ -3174,7 +3421,7 @@ def main():
3174
3421
  job = Jobs.example()
3175
3422
  coop.remote_inference_cost(job)
3176
3423
  job_coop_object = coop.remote_inference_create(job)
3177
- job_coop_results = coop.remote_inference_get(job_coop_object.get("uuid"))
3424
+ job_coop_results = coop.new_remote_inference_get(job_coop_object.get("uuid"))
3178
3425
  coop.get(job_coop_results.get("results_uuid"))
3179
3426
 
3180
3427
  import streamlit as st
@@ -26,7 +26,7 @@ class CoopJobsObjects(CoopObjects):
26
26
 
27
27
  c = Coop()
28
28
  job_details = [
29
- c.remote_inference_get(obj["uuid"], include_json_string=True)
29
+ c.new_remote_inference_get(obj["uuid"], include_json_string=True)
30
30
  for obj in self
31
31
  ]
32
32
 
@@ -53,7 +53,7 @@ class CoopJobsObjects(CoopObjects):
53
53
 
54
54
  for obj in self:
55
55
  if obj.get("results_uuid"):
56
- result = c.get(obj["results_uuid"])
56
+ result = c.pull(obj["results_uuid"], expected_object_type="results")
57
57
  results.append(result)
58
58
 
59
59
  return results
@@ -23,4 +23,6 @@ class CoopRegularObjects(CoopObjects):
23
23
  from ..coop import Coop
24
24
 
25
25
  c = Coop()
26
- return [c.get(obj["uuid"]) for obj in self]
26
+ return [
27
+ c.pull(obj["uuid"], expected_object_type=obj["object_type"]) for obj in self
28
+ ]
@@ -1120,7 +1120,7 @@ class Jobs(Base):
1120
1120
  raise CoopValueError(
1121
1121
  "You must specify both a scenario list and a scenario list method to use scenarios with your survey."
1122
1122
  )
1123
- elif scenario_list_method is "loop":
1123
+ elif scenario_list_method == "loop":
1124
1124
  questions, long_scenario_list = self.survey.to_long_format(self.scenarios)
1125
1125
 
1126
1126
  # Replace the questions with new ones from the loop method
@@ -176,7 +176,7 @@ class JobsRemoteInferenceHandler:
176
176
  from ..coop import Coop
177
177
 
178
178
  coop = Coop()
179
- return coop.remote_inference_get(job_uuid)
179
+ return coop.new_remote_inference_get(job_uuid)
180
180
 
181
181
  def _construct_remote_job_fetcher(
182
182
  self, testing_simulated_response: Optional[Any] = None
@@ -445,9 +445,9 @@ class JobsRemoteInferenceHandler:
445
445
  model_cost_dict["input_cost_credits_with_cache"] = converter.usd_to_credits(
446
446
  input_cost_with_cache
447
447
  )
448
- model_cost_dict[
449
- "output_cost_credits_with_cache"
450
- ] = converter.usd_to_credits(output_cost_with_cache)
448
+ model_cost_dict["output_cost_credits_with_cache"] = (
449
+ converter.usd_to_credits(output_cost_with_cache)
450
+ )
451
451
  return list(expenses_by_model.values())
452
452
 
453
453
  def _fetch_results_and_log(
@@ -305,8 +305,13 @@ class Prompt(PersistenceMixin, RepresentationMixin):
305
305
  Returns (rendered_text, captured_variables).
306
306
  """
307
307
  # Combine replacements.
308
- all_replacements = {**primary_replacement, **additional_replacements}
309
-
308
+ from ..scenarios import Scenario
309
+ # This fixed Issue 2027 - the scenario prefix was not being recoginized in the template
310
+ if isinstance(primary_replacement, Scenario):
311
+ additional = {'scenario': primary_replacement.to_dict()}
312
+ else:
313
+ additional = {}
314
+ all_replacements = {**primary_replacement, **additional_replacements, **additional}
310
315
  # If no replacements and no Jinja variables, just return the text.
311
316
  if not all_replacements and not _find_template_variables(text):
312
317
  return text, template_vars.get_all()
@@ -43,6 +43,7 @@ class Question(metaclass=Meta):
43
43
  subclass = get_question_classes.get(question_type, None)
44
44
  if subclass is None:
45
45
  from .exceptions import QuestionValueError
46
+
46
47
  raise QuestionValueError(
47
48
  f"No question registered with question_type {question_type}"
48
49
  )
@@ -65,7 +66,7 @@ class Question(metaclass=Meta):
65
66
  from ..coop import Coop
66
67
 
67
68
  coop = Coop()
68
- return coop.get(url_or_uuid, "question")
69
+ return coop.pull(url_or_uuid, "question")
69
70
 
70
71
  @classmethod
71
72
  def delete(cls, url_or_uuid: Union[str, UUID]):
@@ -146,6 +147,7 @@ def get_question_class(question_type):
146
147
  q2c = RegisterQuestionsMeta.question_types_to_classes()
147
148
  if question_type not in q2c:
148
149
  from .exceptions import QuestionValueError
150
+
149
151
  raise QuestionValueError(
150
152
  f"The question type, {question_type}, is not recognized. Recognied types are: {q2c.keys()}"
151
153
  )
@@ -171,4 +173,5 @@ question_purpose = {
171
173
 
172
174
  if __name__ == "__main__":
173
175
  import doctest
176
+
174
177
  doctest.testmod()
@@ -512,6 +512,75 @@ class FileStore(Scenario):
512
512
  )
513
513
  return info
514
514
 
515
+ def offload(self, inplace=False) -> "FileStore":
516
+ """
517
+ Offloads base64-encoded content from the FileStore by replacing 'base64_string'
518
+ with 'offloaded'. This reduces memory usage.
519
+
520
+ Args:
521
+ inplace (bool): If True, modify the current FileStore. If False, return a new one.
522
+
523
+ Returns:
524
+ FileStore: The modified FileStore (either self or a new instance).
525
+ """
526
+ if inplace:
527
+ if hasattr(self, "base64_string"):
528
+ self.base64_string = "offloaded"
529
+ return self
530
+ else:
531
+ # Create a copy and offload it
532
+ file_store_dict = self.to_dict()
533
+ if "base64_string" in file_store_dict:
534
+ file_store_dict["base64_string"] = "offloaded"
535
+ return self.__class__.from_dict(file_store_dict)
536
+
537
+ def save_to_gcs_bucket(self, signed_url: str) -> dict:
538
+ """
539
+ Saves the FileStore's file content to a Google Cloud Storage bucket using a signed URL.
540
+
541
+ Args:
542
+ signed_url (str): The signed URL for uploading to GCS bucket
543
+
544
+ Returns:
545
+ dict: Response from the GCS upload operation
546
+
547
+ Raises:
548
+ ValueError: If base64_string is offloaded or missing
549
+ requests.RequestException: If the upload fails
550
+ """
551
+ import requests
552
+ import base64
553
+
554
+ # Check if content is available
555
+ if not hasattr(self, "base64_string") or self.base64_string == "offloaded":
556
+ raise ValueError(
557
+ "File content is not available (offloaded or missing). Cannot upload to GCS."
558
+ )
559
+
560
+ # Decode base64 content to bytes
561
+ try:
562
+ file_content = base64.b64decode(self.base64_string)
563
+ except Exception as e:
564
+ raise ValueError(f"Failed to decode base64 content: {e}")
565
+
566
+ # Prepare headers with proper content type
567
+ headers = {
568
+ "Content-Type": self.mime_type or "application/octet-stream",
569
+ "Content-Length": str(len(file_content)),
570
+ }
571
+
572
+ # Upload to GCS using the signed URL
573
+ response = requests.put(signed_url, data=file_content, headers=headers)
574
+ response.raise_for_status()
575
+
576
+ return {
577
+ "status": "success",
578
+ "status_code": response.status_code,
579
+ "file_size": len(file_content),
580
+ "mime_type": self.mime_type,
581
+ "file_extension": self.suffix,
582
+ }
583
+
515
584
  @classmethod
516
585
  def pull(cls, url_or_uuid: Union[str, UUID]) -> "FileStore":
517
586
  """