edsl 0.1.30.dev1__tar.gz → 0.1.30.dev3__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 (205) hide show
  1. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/PKG-INFO +1 -1
  2. edsl-0.1.30.dev3/edsl/__version__.py +1 -0
  3. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/agents/Agent.py +8 -6
  4. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/agents/AgentList.py +9 -19
  5. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/agents/Invigilator.py +4 -5
  6. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/data/Cache.py +25 -16
  7. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/data/CacheEntry.py +6 -7
  8. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/data_transfer_models.py +4 -0
  9. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/Jobs.py +17 -2
  10. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/buckets/ModelBuckets.py +10 -0
  11. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/buckets/TokenBucket.py +19 -2
  12. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/Interview.py +7 -6
  13. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/runners/JobsRunnerAsyncio.py +4 -0
  14. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/tasks/QuestionTaskCreator.py +14 -6
  15. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/language_models/LanguageModel.py +4 -5
  16. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/notebooks/Notebook.py +9 -9
  17. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionFreeText.py +4 -2
  18. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/Results.py +2 -2
  19. edsl-0.1.30.dev3/edsl/scenarios/FileStore.py +299 -0
  20. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/scenarios/Scenario.py +12 -19
  21. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/scenarios/ScenarioList.py +8 -6
  22. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/study/Study.py +3 -5
  23. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/Survey.py +9 -11
  24. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/pyproject.toml +1 -1
  25. edsl-0.1.30.dev1/edsl/__version__.py +0 -1
  26. edsl-0.1.30.dev1/edsl/scenarios/FileStore.py +0 -140
  27. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/LICENSE +0 -0
  28. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/README.md +0 -0
  29. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/Base.py +0 -0
  30. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/BaseDiff.py +0 -0
  31. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/__init__.py +0 -0
  32. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/agents/InvigilatorBase.py +0 -0
  33. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/agents/PromptConstructionMixin.py +0 -0
  34. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/agents/__init__.py +0 -0
  35. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/agents/descriptors.py +0 -0
  36. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/base/Base.py +0 -0
  37. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/config.py +0 -0
  38. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/AgentConstructionMixin.py +0 -0
  39. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/Conjure.py +0 -0
  40. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/InputData.py +0 -0
  41. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/InputDataCSV.py +0 -0
  42. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/InputDataMixinQuestionStats.py +0 -0
  43. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/InputDataPyRead.py +0 -0
  44. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/InputDataSPSS.py +0 -0
  45. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/InputDataStata.py +0 -0
  46. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/QuestionOptionMixin.py +0 -0
  47. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/QuestionTypeMixin.py +0 -0
  48. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/RawQuestion.py +0 -0
  49. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/SurveyResponses.py +0 -0
  50. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/__init__.py +0 -0
  51. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/examples/placeholder.txt +0 -0
  52. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/naming_utilities.py +0 -0
  53. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conjure/utilities.py +0 -0
  54. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conversation/Conversation.py +0 -0
  55. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conversation/car_buying.py +0 -0
  56. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conversation/mug_negotiation.py +0 -0
  57. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/conversation/next_speaker_utilities.py +0 -0
  58. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/coop/__init__.py +0 -0
  59. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/coop/coop.py +0 -0
  60. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/coop/utils.py +0 -0
  61. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/data/CacheHandler.py +0 -0
  62. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/data/SQLiteDict.py +0 -0
  63. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/data/__init__.py +0 -0
  64. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/data/orm.py +0 -0
  65. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/enums.py +0 -0
  66. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/__init__.py +0 -0
  67. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/agents.py +0 -0
  68. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/configuration.py +0 -0
  69. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/coop.py +0 -0
  70. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/data.py +0 -0
  71. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/general.py +0 -0
  72. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/jobs.py +0 -0
  73. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/language_models.py +0 -0
  74. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/prompts.py +0 -0
  75. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/questions.py +0 -0
  76. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/results.py +0 -0
  77. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/exceptions/surveys.py +0 -0
  78. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/AnthropicService.py +0 -0
  79. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/DeepInfraService.py +0 -0
  80. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/GoogleService.py +0 -0
  81. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/InferenceServiceABC.py +0 -0
  82. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/InferenceServicesCollection.py +0 -0
  83. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/OpenAIService.py +0 -0
  84. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/__init__.py +0 -0
  85. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/models_available_cache.py +0 -0
  86. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/rate_limits_cache.py +0 -0
  87. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/registry.py +0 -0
  88. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/inference_services/write_available.py +0 -0
  89. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/Answers.py +0 -0
  90. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/__init__.py +0 -0
  91. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/buckets/BucketCollection.py +0 -0
  92. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/InterviewStatistic.py +0 -0
  93. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/InterviewStatisticsCollection.py +0 -0
  94. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/InterviewStatusDictionary.py +0 -0
  95. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/InterviewStatusLog.py +0 -0
  96. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/InterviewStatusMixin.py +0 -0
  97. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/InterviewTaskBuildingMixin.py +0 -0
  98. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/ReportErrors.py +0 -0
  99. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/interview_exception_tracking.py +0 -0
  100. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/interview_status_enum.py +0 -0
  101. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/interviews/retry_management.py +0 -0
  102. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/runners/JobsRunnerStatusData.py +0 -0
  103. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/runners/JobsRunnerStatusMixin.py +0 -0
  104. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/tasks/TaskCreators.py +0 -0
  105. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/tasks/TaskHistory.py +0 -0
  106. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/tasks/TaskStatusLog.py +0 -0
  107. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/tasks/task_management.py +0 -0
  108. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/tasks/task_status_enum.py +0 -0
  109. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/tokens/InterviewTokenUsage.py +0 -0
  110. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/jobs/tokens/TokenUsage.py +0 -0
  111. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/language_models/ModelList.py +0 -0
  112. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/language_models/RegisterLanguageModelsMeta.py +0 -0
  113. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/language_models/__init__.py +0 -0
  114. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/language_models/registry.py +0 -0
  115. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/language_models/repair.py +0 -0
  116. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/language_models/unused/ReplicateBase.py +0 -0
  117. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/notebooks/__init__.py +0 -0
  118. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/Prompt.py +0 -0
  119. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/QuestionInstructionsBase.py +0 -0
  120. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/__init__.py +0 -0
  121. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/agent_instructions.py +0 -0
  122. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/agent_persona.py +0 -0
  123. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/question_budget.py +0 -0
  124. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/question_checkbox.py +0 -0
  125. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/question_extract.py +0 -0
  126. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/question_freetext.py +0 -0
  127. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/question_linear_scale.py +0 -0
  128. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/question_list.py +0 -0
  129. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/question_multiple_choice.py +0 -0
  130. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/question_numerical.py +0 -0
  131. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/library/question_rank.py +0 -0
  132. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/prompt_config.py +0 -0
  133. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/prompts/registry.py +0 -0
  134. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/AnswerValidatorMixin.py +0 -0
  135. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionBase.py +0 -0
  136. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionBudget.py +0 -0
  137. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionCheckBox.py +0 -0
  138. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionExtract.py +0 -0
  139. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionFunctional.py +0 -0
  140. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionList.py +0 -0
  141. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionMultipleChoice.py +0 -0
  142. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionNumerical.py +0 -0
  143. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/QuestionRank.py +0 -0
  144. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/RegisterQuestionsMeta.py +0 -0
  145. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/SimpleAskMixin.py +0 -0
  146. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/__init__.py +0 -0
  147. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/compose_questions.py +0 -0
  148. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/derived/QuestionLikertFive.py +0 -0
  149. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/derived/QuestionLinearScale.py +0 -0
  150. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/derived/QuestionTopK.py +0 -0
  151. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/derived/QuestionYesNo.py +0 -0
  152. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/derived/__init__.py +0 -0
  153. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/descriptors.py +0 -0
  154. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/question_registry.py +0 -0
  155. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/questions/settings.py +0 -0
  156. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/Dataset.py +0 -0
  157. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/DatasetExportMixin.py +0 -0
  158. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/Result.py +0 -0
  159. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/ResultsDBMixin.py +0 -0
  160. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/ResultsExportMixin.py +0 -0
  161. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/ResultsFetchMixin.py +0 -0
  162. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/ResultsGGMixin.py +0 -0
  163. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/ResultsToolsMixin.py +0 -0
  164. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/results/__init__.py +0 -0
  165. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/scenarios/ScenarioHtmlMixin.py +0 -0
  166. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/scenarios/ScenarioImageMixin.py +0 -0
  167. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/scenarios/ScenarioListExportMixin.py +0 -0
  168. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/scenarios/ScenarioListPdfMixin.py +0 -0
  169. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/scenarios/__init__.py +0 -0
  170. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/shared.py +0 -0
  171. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/study/ObjectEntry.py +0 -0
  172. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/study/ProofOfWork.py +0 -0
  173. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/study/SnapShot.py +0 -0
  174. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/study/__init__.py +0 -0
  175. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/DAG.py +0 -0
  176. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/Memory.py +0 -0
  177. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/MemoryPlan.py +0 -0
  178. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/Rule.py +0 -0
  179. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/RuleCollection.py +0 -0
  180. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/SurveyCSS.py +0 -0
  181. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/SurveyExportMixin.py +0 -0
  182. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/SurveyFlowVisualizationMixin.py +0 -0
  183. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/__init__.py +0 -0
  184. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/base.py +0 -0
  185. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/surveys/descriptors.py +0 -0
  186. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/tools/__init__.py +0 -0
  187. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/tools/clusters.py +0 -0
  188. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/tools/embeddings.py +0 -0
  189. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/tools/embeddings_plotting.py +0 -0
  190. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/tools/plotting.py +0 -0
  191. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/tools/summarize.py +0 -0
  192. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/SystemInfo.py +0 -0
  193. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/__init__.py +0 -0
  194. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/ast_utilities.py +0 -0
  195. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/data/Registry.py +0 -0
  196. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/data/__init__.py +0 -0
  197. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/data/scooter_results.json +0 -0
  198. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/decorators.py +0 -0
  199. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/gcp_bucket/__init__.py +0 -0
  200. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/gcp_bucket/cloud_storage.py +0 -0
  201. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/gcp_bucket/simple_example.py +0 -0
  202. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/interface.py +0 -0
  203. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/repair_functions.py +0 -0
  204. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/restricted_python.py +0 -0
  205. {edsl-0.1.30.dev1 → edsl-0.1.30.dev3}/edsl/utilities/utilities.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.30.dev1
3
+ Version: 0.1.30.dev3
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.30.dev3"
@@ -4,7 +4,8 @@ from __future__ import annotations
4
4
  import copy
5
5
  import inspect
6
6
  import types
7
- from typing import Any, Callable, Optional, Union, Dict, Sequence
7
+ from typing import Callable, Optional, Union
8
+ from uuid import uuid4
8
9
  from edsl.Base import Base
9
10
 
10
11
  from edsl.exceptions.agents import (
@@ -688,13 +689,14 @@ class Agent(Base):
688
689
  return table
689
690
 
690
691
  @classmethod
691
- def example(cls) -> Agent:
692
- """Return an example agent.
692
+ def example(cls, randomize: bool = False) -> Agent:
693
+ """
694
+ Returns an example Agent instance.
693
695
 
694
- >>> Agent.example()
695
- Agent(traits = {'age': 22, 'hair': 'brown', 'height': 5.5})
696
+ :param randomize: If True, adds a random string to the value of an example key.
696
697
  """
697
- return cls(traits={"age": 22, "hair": "brown", "height": 5.5})
698
+ addition = "" if not randomize else str(uuid4())
699
+ return cls(traits={"age": 22, "hair": f"brown{addition}", "height": 5.5})
698
700
 
699
701
  def code(self) -> str:
700
702
  """Return the code for the agent.
@@ -11,23 +11,15 @@ Example usage:
11
11
  """
12
12
 
13
13
  from __future__ import annotations
14
+ import csv
15
+ import json
14
16
  from collections import UserList
15
- from typing import Optional, Union, Sequence, List, Any
17
+ from typing import Any, List, Optional, Union
16
18
  from rich import print_json
17
19
  from rich.table import Table
18
- import json
19
- import csv
20
-
21
-
22
20
  from simpleeval import EvalWithCompoundTypes
23
-
24
21
  from edsl.Base import Base
25
-
26
- # from edsl.agents import Agent
27
- from edsl.utilities.decorators import (
28
- add_edsl_version,
29
- remove_edsl_version,
30
- )
22
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
31
23
 
32
24
 
33
25
  class AgentList(UserList, Base):
@@ -239,17 +231,15 @@ class AgentList(UserList, Base):
239
231
  return cls(agents)
240
232
 
241
233
  @classmethod
242
- def example(cls) -> "AgentList":
243
- """Return an example AgentList.
244
-
245
- >>> al = AgentList.example()
246
- >>> len(al)
247
- 2
234
+ def example(cls, randomize: bool = False) -> AgentList:
235
+ """
236
+ Returns an example AgentList instance.
248
237
 
238
+ :param randomize: If True, uses Agent's randomize method.
249
239
  """
250
240
  from edsl.agents.Agent import Agent
251
241
 
252
- return cls([Agent.example(), Agent.example()])
242
+ return cls([Agent.example(randomize), Agent.example(randomize)])
253
243
 
254
244
  @classmethod
255
245
  def from_list(self, trait_name: str, values: List[Any]):
@@ -74,15 +74,14 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
74
74
 
75
75
  This cleans up the raw response to make it suitable to pass to AgentResponseDict.
76
76
  """
77
- # not actually used, but this removes the temptation to delete agent from the signature
78
77
  _ = agent
79
78
  try:
80
79
  response = question._validate_answer(raw_response)
81
80
  except Exception as e:
81
+ """If the response is invalid, remove it from the cache and raise the exception."""
82
82
  self._remove_from_cache(raw_response)
83
83
  raise e
84
84
 
85
- # breakpoint()
86
85
  question_dict = self.survey.question_names_to_questions()
87
86
  for other_question, answer in self.current_answers.items():
88
87
  if other_question in question_dict:
@@ -95,12 +94,10 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
95
94
  question_dict[new_question].comment = answer
96
95
 
97
96
  combined_dict = {**question_dict, **scenario}
98
- # print("combined_dict: ", combined_dict)
99
- # print("response: ", response)
100
- # breakpoint()
101
97
  answer = question._translate_answer_code_to_answer(
102
98
  response["answer"], combined_dict
103
99
  )
100
+ # breakpoint()
104
101
  data = {
105
102
  "answer": answer,
106
103
  "comment": response.get(
@@ -111,6 +108,8 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
111
108
  "cached_response": raw_response.get("cached_response", None),
112
109
  "usage": raw_response.get("usage", {}),
113
110
  "raw_model_response": raw_model_response,
111
+ "cache_used": raw_response.get("cache_used", False),
112
+ "cache_key": raw_response.get("cache_key", None),
114
113
  }
115
114
  return AgentResponseDict(**data)
116
115
 
@@ -7,17 +7,10 @@ import json
7
7
  import os
8
8
  import warnings
9
9
  from typing import Optional, Union
10
- import time
11
- from edsl.config import CONFIG
12
- from edsl.data.CacheEntry import CacheEntry
13
-
14
- # from edsl.data.SQLiteDict import SQLiteDict
15
10
  from edsl.Base import Base
11
+ from edsl.data.CacheEntry import CacheEntry
16
12
  from edsl.utilities.utilities import dict_hash
17
- from edsl.utilities.decorators import (
18
- add_edsl_version,
19
- remove_edsl_version,
20
- )
13
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
21
14
 
22
15
 
23
16
  class Cache(Base):
@@ -41,6 +34,7 @@ class Cache(Base):
41
34
  data: Optional[Union["SQLiteDict", dict]] = None,
42
35
  immediate_write: bool = True,
43
36
  method=None,
37
+ verbose=False,
44
38
  ):
45
39
  """
46
40
  Create two dictionaries to store the cache data.
@@ -59,6 +53,7 @@ class Cache(Base):
59
53
  self.new_entries = {}
60
54
  self.new_entries_to_write_later = {}
61
55
  self.coop = None
56
+ self.verbose = verbose
62
57
 
63
58
  self.filename = filename
64
59
  if filename and data:
@@ -122,7 +117,7 @@ class Cache(Base):
122
117
  system_prompt: str,
123
118
  user_prompt: str,
124
119
  iteration: int,
125
- ) -> Union[None, str]:
120
+ ) -> tuple(Union[None, str], str):
126
121
  """
127
122
  Fetch a value (LLM output) from the cache.
128
123
 
@@ -135,7 +130,7 @@ class Cache(Base):
135
130
  Return None if the response is not found.
136
131
 
137
132
  >>> c = Cache()
138
- >>> c.fetch(model="gpt-3", parameters="default", system_prompt="Hello", user_prompt="Hi", iteration=1) is None
133
+ >>> c.fetch(model="gpt-3", parameters="default", system_prompt="Hello", user_prompt="Hi", iteration=1)[0] is None
139
134
  True
140
135
 
141
136
 
@@ -151,8 +146,13 @@ class Cache(Base):
151
146
  )
152
147
  entry = self.data.get(key, None)
153
148
  if entry is not None:
149
+ if self.verbose:
150
+ print(f"Cache hit for key: {key}")
154
151
  self.fetched_data[key] = entry
155
- return None if entry is None else entry.output
152
+ else:
153
+ if self.verbose:
154
+ print(f"Cache miss for key: {key}")
155
+ return None if entry is None else entry.output, key
156
156
 
157
157
  def store(
158
158
  self,
@@ -354,6 +354,9 @@ class Cache(Base):
354
354
  for key, entry in self.new_entries_to_write_later.items():
355
355
  self.data[key] = entry
356
356
 
357
+ if self.filename:
358
+ self.write(self.filename)
359
+
357
360
  ####################
358
361
  # DUNDER / USEFUL
359
362
  ####################
@@ -470,12 +473,18 @@ class Cache(Base):
470
473
  webbrowser.open("file://" + filepath)
471
474
 
472
475
  @classmethod
473
- def example(cls) -> Cache:
476
+ def example(cls, randomize: bool = False) -> Cache:
474
477
  """
475
- Return an example Cache.
476
- The example Cache has one entry.
478
+ Returns an example Cache instance.
479
+
480
+ :param randomize: If True, uses CacheEntry's randomize method.
477
481
  """
478
- return cls(data={CacheEntry.example().key: CacheEntry.example()})
482
+ return cls(
483
+ data={
484
+ CacheEntry.example(randomize).key: CacheEntry.example(),
485
+ CacheEntry.example(randomize).key: CacheEntry.example(),
486
+ }
487
+ )
479
488
 
480
489
 
481
490
  if __name__ == "__main__":
@@ -2,11 +2,8 @@ from __future__ import annotations
2
2
  import json
3
3
  import datetime
4
4
  import hashlib
5
- import random
6
5
  from typing import Optional
7
-
8
-
9
- # TODO: Timestamp should probably be float?
6
+ from uuid import uuid4
10
7
 
11
8
 
12
9
  class CacheEntry:
@@ -151,10 +148,12 @@ class CacheEntry:
151
148
  @classmethod
152
149
  def example(cls, randomize: bool = False) -> CacheEntry:
153
150
  """
154
- Returns a CacheEntry example.
151
+ Returns an example CacheEntry instance.
152
+
153
+ :param randomize: If True, adds a random string to the system prompt.
155
154
  """
156
- # if random, create a random number for 0-100
157
- addition = "" if not randomize else str(random.randint(0, 1000))
155
+ # if random, create a uuid
156
+ addition = "" if not randomize else str(uuid4())
158
157
  return CacheEntry(
159
158
  model="gpt-3.5-turbo",
160
159
  parameters={"temperature": 0.5},
@@ -17,6 +17,8 @@ class AgentResponseDict(UserDict):
17
17
  cached_response=None,
18
18
  raw_model_response=None,
19
19
  simple_model_raw_response=None,
20
+ cache_used=None,
21
+ cache_key=None,
20
22
  ):
21
23
  """Initialize the AgentResponseDict object."""
22
24
  usage = usage or {"prompt_tokens": 0, "completion_tokens": 0}
@@ -30,5 +32,7 @@ class AgentResponseDict(UserDict):
30
32
  "cached_response": cached_response,
31
33
  "raw_model_response": raw_model_response,
32
34
  "simple_model_raw_response": simple_model_raw_response,
35
+ "cache_used": cache_used,
36
+ "cache_key": cache_key,
33
37
  }
34
38
  )
@@ -461,6 +461,13 @@ class Jobs(Base):
461
461
  remote_inference = False
462
462
 
463
463
  if remote_inference:
464
+ from edsl.agents.Agent import Agent
465
+ from edsl.language_models.registry import Model
466
+ from edsl.results.Result import Result
467
+ from edsl.results.Results import Results
468
+ from edsl.scenarios.Scenario import Scenario
469
+ from edsl.surveys.Survey import Survey
470
+
464
471
  self._output("Remote inference activated. Sending job to server...")
465
472
  if remote_cache:
466
473
  self._output(
@@ -680,7 +687,9 @@ class Jobs(Base):
680
687
  # Example methods
681
688
  #######################
682
689
  @classmethod
683
- def example(cls, throw_exception_probability=0) -> Jobs:
690
+ def example(
691
+ cls, throw_exception_probability: int = 0, randomize: bool = False
692
+ ) -> Jobs:
684
693
  """Return an example Jobs instance.
685
694
 
686
695
  :param throw_exception_probability: the probability that an exception will be thrown when answering a question. This is useful for testing error handling.
@@ -690,10 +699,13 @@ class Jobs(Base):
690
699
 
691
700
  """
692
701
  import random
702
+ from uuid import uuid4
693
703
  from edsl.questions import QuestionMultipleChoice
694
704
  from edsl.agents.Agent import Agent
695
705
  from edsl.scenarios.Scenario import Scenario
696
706
 
707
+ addition = "" if not randomize else str(uuid4())
708
+
697
709
  # (status, question, period)
698
710
  agent_answers = {
699
711
  ("Joyful", "how_feeling", "morning"): "OK",
@@ -736,7 +748,10 @@ class Jobs(Base):
736
748
  base_survey = Survey(questions=[q1, q2])
737
749
 
738
750
  scenario_list = ScenarioList(
739
- [Scenario({"period": "morning"}), Scenario({"period": "afternoon"})]
751
+ [
752
+ Scenario({"period": f"morning{addition}"}),
753
+ Scenario({"period": "afternoon"}),
754
+ ]
740
755
  )
741
756
  job = base_survey.by(scenario_list).by(joy_agent, sad_agent)
742
757
 
@@ -25,6 +25,16 @@ class ModelBuckets:
25
25
  tokens_bucket=self.tokens_bucket + other.tokens_bucket,
26
26
  )
27
27
 
28
+ def turbo_mode_on(self):
29
+ """Set the refill rate to infinity for both buckets."""
30
+ self.requests_bucket.turbo_mode_on()
31
+ self.tokens_bucket.turbo_mode_on()
32
+
33
+ def turbo_mode_off(self):
34
+ """Restore the refill rate to its original value for both buckets."""
35
+ self.requests_bucket.turbo_mode_off()
36
+ self.tokens_bucket.turbo_mode_off()
37
+
28
38
  @classmethod
29
39
  def infinity_bucket(cls, model_name: str = "not_specified") -> "ModelBuckets":
30
40
  """Create a bucket with infinite capacity and refill rate."""
@@ -17,11 +17,28 @@ class TokenBucket:
17
17
  self.bucket_name = bucket_name
18
18
  self.bucket_type = bucket_type
19
19
  self.capacity = capacity # Maximum number of tokens
20
+ self._old_capacity = capacity
20
21
  self.tokens = capacity # Current number of available tokens
21
22
  self.refill_rate = refill_rate # Rate at which tokens are refilled
23
+ self._old_refill_rate = refill_rate
22
24
  self.last_refill = time.monotonic() # Last refill time
23
-
24
25
  self.log: List[Any] = []
26
+ self.turbo_mode = False
27
+
28
+ def turbo_mode_on(self):
29
+ """Set the refill rate to infinity."""
30
+ if self.turbo_mode:
31
+ pass
32
+ else:
33
+ self.turbo_mode = True
34
+ self.capacity = float("inf")
35
+ self.refill_rate = float("inf")
36
+
37
+ def turbo_mode_off(self):
38
+ """Restore the refill rate to its original value."""
39
+ self.turbo_mode = False
40
+ self.capacity = self._old_capacity
41
+ self.refill_rate = self._old_refill_rate
25
42
 
26
43
  def __add__(self, other) -> "TokenBucket":
27
44
  """Combine two token buckets.
@@ -98,7 +115,7 @@ class TokenBucket:
98
115
  raise ValueError(msg)
99
116
  while self.tokens < amount:
100
117
  self.refill()
101
- await asyncio.sleep(0.1) # Sleep briefly to prevent busy waiting
118
+ await asyncio.sleep(0.01) # Sleep briefly to prevent busy waiting
102
119
  self.tokens -= amount
103
120
 
104
121
  now = time.monotonic()
@@ -30,14 +30,14 @@ class Interview(InterviewStatusMixin, InterviewTaskBuildingMixin):
30
30
 
31
31
  def __init__(
32
32
  self,
33
- agent: Agent,
34
- survey: Survey,
35
- scenario: Scenario,
36
- model: Type[LanguageModel],
37
- debug: bool = False,
33
+ agent: "Agent",
34
+ survey: "Survey",
35
+ scenario: "Scenario",
36
+ model: Type["LanguageModel"],
37
+ debug: Optional[bool] = False,
38
38
  iteration: int = 0,
39
39
  cache: "Cache" = None,
40
- sidecar_model: LanguageModel = None,
40
+ sidecar_model: "LanguageModel" = None,
41
41
  ):
42
42
  """Initialize the Interview instance.
43
43
 
@@ -99,6 +99,7 @@ class Interview(InterviewStatusMixin, InterviewTaskBuildingMixin):
99
99
  if model_buckets is None or hasattr(self.agent, "answer_question_directly"):
100
100
  model_buckets = ModelBuckets.infinity_bucket()
101
101
 
102
+ # FOR TESTING
102
103
  # model_buckets = ModelBuckets.infinity_bucket()
103
104
 
104
105
  ## build the tasks using the InterviewTaskBuildingMixin
@@ -88,6 +88,8 @@ class JobsRunnerAsyncio(JobsRunnerStatusMixin):
88
88
  self.total_interviews.append(interview)
89
89
 
90
90
  async def run_async(self, cache=None) -> Results:
91
+ from edsl.results.Results import Results
92
+
91
93
  if cache is None:
92
94
  self.cache = Cache()
93
95
  else:
@@ -98,6 +100,8 @@ class JobsRunnerAsyncio(JobsRunnerStatusMixin):
98
100
  return Results(survey=self.jobs.survey, data=data)
99
101
 
100
102
  def simple_run(self):
103
+ from edsl.results.Results import Results
104
+
101
105
  data = asyncio.run(self.run_async())
102
106
  return Results(survey=self.jobs.survey, data=data)
103
107
 
@@ -144,12 +144,20 @@ class QuestionTaskCreator(UserList):
144
144
  self.task_status = TaskStatus.FAILED
145
145
  raise e
146
146
 
147
- if "cached_response" in results:
148
- if results["cached_response"]:
149
- # Gives back the tokens b/c the API was not called.
150
- self.tokens_bucket.add_tokens(requested_tokens)
151
- self.requests_bucket.add_tokens(1)
152
- self.from_cache = True
147
+ ## This isn't working
148
+ # breakpoint()
149
+ if results.get("cache_used", False):
150
+ self.tokens_bucket.add_tokens(requested_tokens)
151
+ self.requests_bucket.add_tokens(1)
152
+ self.from_cache = True
153
+ # print("Turning on turbo!")
154
+ self.tokens_bucket.turbo_mode_on()
155
+ self.requests_bucket.turbo_mode_on()
156
+ else:
157
+ # breakpoint()
158
+ # print("Turning off turbo!")
159
+ self.tokens_bucket.turbo_mode_off()
160
+ self.requests_bucket.turbo_mode_off()
153
161
 
154
162
  _ = results.pop("cached_response", None)
155
163
 
@@ -323,12 +323,10 @@ class LanguageModel(
323
323
  image_hash = hashlib.md5(encoded_image.encode()).hexdigest()
324
324
  cache_call_params["user_prompt"] = f"{user_prompt} {image_hash}"
325
325
 
326
- cached_response = cache.fetch(**cache_call_params)
327
-
326
+ cached_response, cache_key = cache.fetch(**cache_call_params)
328
327
  if cached_response:
329
328
  response = json.loads(cached_response)
330
329
  cache_used = True
331
- cache_key = None
332
330
  else:
333
331
  remote_call = hasattr(self, "remote") and self.remote
334
332
  f = (
@@ -340,7 +338,7 @@ class LanguageModel(
340
338
  if encoded_image:
341
339
  params["encoded_image"] = encoded_image
342
340
  response = await f(**params)
343
- cache_key = cache.store(
341
+ new_cache_key = cache.store(
344
342
  user_prompt=user_prompt,
345
343
  model=str(self.model),
346
344
  parameters=self.parameters,
@@ -348,6 +346,7 @@ class LanguageModel(
348
346
  response=response,
349
347
  iteration=iteration,
350
348
  )
349
+ assert new_cache_key == cache_key
351
350
  cache_used = False
352
351
 
353
352
  return response, cache_used, cache_key
@@ -412,7 +411,7 @@ class LanguageModel(
412
411
 
413
412
  dict_response.update(
414
413
  {
415
- "cached_used": cache_used,
414
+ "cache_used": cache_used,
416
415
  "cache_key": cache_key,
417
416
  "usage": raw_response.get("usage", {}),
418
417
  "raw_model_response": raw_response,
@@ -1,14 +1,11 @@
1
1
  """A Notebook is a utility class that allows you to easily share/pull ipynbs from Coop."""
2
2
 
3
+ from __future__ import annotations
3
4
  import json
4
5
  from typing import Dict, List, Optional
5
-
6
-
6
+ from uuid import uuid4
7
7
  from edsl.Base import Base
8
- from edsl.utilities.decorators import (
9
- add_edsl_version,
10
- remove_edsl_version,
11
- )
8
+ from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
12
9
 
13
10
 
14
11
  class Notebook(Base):
@@ -192,10 +189,13 @@ class Notebook(Base):
192
189
  return table
193
190
 
194
191
  @classmethod
195
- def example(cls) -> "Notebook":
192
+ def example(cls, randomize: bool = False) -> Notebook:
196
193
  """
197
- Return an example Notebook.
194
+ Returns an example Notebook instance.
195
+
196
+ :param randomize: If True, adds a random string one of the cells' output.
198
197
  """
198
+ addition = "" if not randomize else str(uuid4())
199
199
  cells = [
200
200
  {
201
201
  "cell_type": "markdown",
@@ -210,7 +210,7 @@ class Notebook(Base):
210
210
  {
211
211
  "name": "stdout",
212
212
  "output_type": "stream",
213
- "text": "Hello world!\n",
213
+ "text": f"Hello world!\n{addition}",
214
214
  }
215
215
  ],
216
216
  "source": 'print("Hello world!")',
@@ -1,6 +1,7 @@
1
1
  from __future__ import annotations
2
2
  import textwrap
3
3
  from typing import Any, Optional
4
+ from uuid import uuid4
4
5
  from edsl.questions.QuestionBase import QuestionBase
5
6
 
6
7
 
@@ -65,9 +66,10 @@ class QuestionFreeText(QuestionBase):
65
66
  return question_html_content
66
67
 
67
68
  @classmethod
68
- def example(cls) -> QuestionFreeText:
69
+ def example(cls, randomize: bool = False) -> QuestionFreeText:
69
70
  """Return an example instance of a free text question."""
70
- return cls(question_name="how_are_you", question_text="How are you?")
71
+ addition = "" if not randomize else str(uuid4())
72
+ return cls(question_name="how_are_you", question_text=f"How are you?{addition}")
71
73
 
72
74
 
73
75
  def main():
@@ -949,7 +949,7 @@ class Results(UserList, Mixins, Base):
949
949
  return Results(survey=self.survey, data=new_data, created_columns=None)
950
950
 
951
951
  @classmethod
952
- def example(cls, debug: bool = False) -> Results:
952
+ def example(cls, debug: bool = False, randomize: bool = False) -> Results:
953
953
  """Return an example `Results` object.
954
954
 
955
955
  Example usage:
@@ -962,7 +962,7 @@ class Results(UserList, Mixins, Base):
962
962
  from edsl.data.Cache import Cache
963
963
 
964
964
  c = Cache()
965
- job = Jobs.example()
965
+ job = Jobs.example(randomize=randomize)
966
966
  results = job.run(cache=c, debug=debug)
967
967
  return results
968
968