edsl 0.1.36.dev5__tar.gz → 0.1.37__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 (287) hide show
  1. {edsl-0.1.36.dev5 → edsl-0.1.37}/PKG-INFO +1 -1
  2. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/__init__.py +1 -0
  3. edsl-0.1.37/edsl/__version__.py +1 -0
  4. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/agents/Agent.py +92 -41
  5. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/agents/AgentList.py +15 -2
  6. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/agents/InvigilatorBase.py +15 -25
  7. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/agents/PromptConstructor.py +149 -108
  8. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/agents/descriptors.py +17 -4
  9. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/AgentConstructionMixin.py +11 -3
  10. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conversation/Conversation.py +66 -14
  11. edsl-0.1.37/edsl/conversation/chips.py +95 -0
  12. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/coop/coop.py +148 -39
  13. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/data/Cache.py +1 -1
  14. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/data/RemoteCacheSync.py +25 -12
  15. edsl-0.1.37/edsl/exceptions/BaseException.py +21 -0
  16. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/exceptions/__init__.py +7 -3
  17. edsl-0.1.37/edsl/exceptions/agents.py +38 -0
  18. edsl-0.1.37/edsl/exceptions/results.py +29 -0
  19. edsl-0.1.37/edsl/exceptions/scenarios.py +22 -0
  20. edsl-0.1.37/edsl/exceptions/surveys.py +37 -0
  21. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/AwsBedrock.py +7 -2
  22. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/InferenceServicesCollection.py +42 -13
  23. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/models_available_cache.py +25 -1
  24. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/Jobs.py +306 -71
  25. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/interviews/Interview.py +24 -14
  26. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/interviews/InterviewExceptionCollection.py +1 -1
  27. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/interviews/InterviewExceptionEntry.py +17 -13
  28. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/interviews/ReportErrors.py +2 -2
  29. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/runners/JobsRunnerAsyncio.py +10 -9
  30. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/tasks/TaskHistory.py +1 -0
  31. edsl-0.1.37/edsl/language_models/KeyLookup.py +30 -0
  32. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/LanguageModel.py +47 -59
  33. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/__init__.py +1 -0
  34. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/prompts/Prompt.py +11 -12
  35. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionBase.py +53 -13
  36. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionBasePromptsMixin.py +1 -33
  37. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionFreeText.py +1 -0
  38. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionFunctional.py +2 -2
  39. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/descriptors.py +23 -28
  40. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/DatasetExportMixin.py +25 -1
  41. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/Result.py +27 -10
  42. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/Results.py +34 -121
  43. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/ResultsDBMixin.py +1 -1
  44. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/Selector.py +18 -1
  45. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/scenarios/FileStore.py +20 -5
  46. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/scenarios/Scenario.py +52 -13
  47. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/scenarios/ScenarioHtmlMixin.py +7 -2
  48. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/scenarios/ScenarioList.py +12 -1
  49. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/scenarios/__init__.py +2 -0
  50. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/Rule.py +10 -4
  51. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/Survey.py +100 -77
  52. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/utilities.py +18 -0
  53. {edsl-0.1.36.dev5 → edsl-0.1.37}/pyproject.toml +10 -19
  54. edsl-0.1.36.dev5/edsl/__version__.py +0 -1
  55. edsl-0.1.36.dev5/edsl/exceptions/agents.py +0 -40
  56. edsl-0.1.36.dev5/edsl/exceptions/results.py +0 -26
  57. edsl-0.1.36.dev5/edsl/exceptions/surveys.py +0 -34
  58. {edsl-0.1.36.dev5 → edsl-0.1.37}/LICENSE +0 -0
  59. {edsl-0.1.36.dev5 → edsl-0.1.37}/README.md +0 -0
  60. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/Base.py +0 -0
  61. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/BaseDiff.py +0 -0
  62. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/TemplateLoader.py +0 -0
  63. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/agents/Invigilator.py +0 -0
  64. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/agents/__init__.py +0 -0
  65. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/agents/prompt_helpers.py +0 -0
  66. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/AutoStudy.py +0 -0
  67. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/StageBase.py +0 -0
  68. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/StageGenerateSurvey.py +0 -0
  69. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/StageLabelQuestions.py +0 -0
  70. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/StagePersona.py +0 -0
  71. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/StagePersonaDimensionValueRanges.py +0 -0
  72. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/StagePersonaDimensionValues.py +0 -0
  73. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/StagePersonaDimensions.py +0 -0
  74. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/StageQuestions.py +0 -0
  75. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/SurveyCreatorPipeline.py +0 -0
  76. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/auto/utilities.py +0 -0
  77. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/base/Base.py +0 -0
  78. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/config.py +0 -0
  79. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/Conjure.py +0 -0
  80. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/InputData.py +0 -0
  81. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/InputDataCSV.py +0 -0
  82. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/InputDataMixinQuestionStats.py +0 -0
  83. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/InputDataPyRead.py +0 -0
  84. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/InputDataSPSS.py +0 -0
  85. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/InputDataStata.py +0 -0
  86. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/QuestionOptionMixin.py +0 -0
  87. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/QuestionTypeMixin.py +0 -0
  88. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/RawQuestion.py +0 -0
  89. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/SurveyResponses.py +0 -0
  90. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/__init__.py +0 -0
  91. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/examples/placeholder.txt +0 -0
  92. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/naming_utilities.py +0 -0
  93. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conjure/utilities.py +0 -0
  94. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conversation/car_buying.py +0 -0
  95. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conversation/mug_negotiation.py +0 -0
  96. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/conversation/next_speaker_utilities.py +0 -0
  97. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/coop/PriceFetcher.py +0 -0
  98. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/coop/__init__.py +0 -0
  99. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/coop/utils.py +0 -0
  100. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/data/CacheEntry.py +0 -0
  101. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/data/CacheHandler.py +0 -0
  102. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/data/SQLiteDict.py +0 -0
  103. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/data/__init__.py +0 -0
  104. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/data/orm.py +0 -0
  105. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/data_transfer_models.py +0 -0
  106. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/enums.py +0 -0
  107. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/exceptions/configuration.py +0 -0
  108. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/exceptions/coop.py +0 -0
  109. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/exceptions/data.py +0 -0
  110. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/exceptions/general.py +0 -0
  111. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/exceptions/jobs.py +0 -0
  112. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/exceptions/language_models.py +0 -0
  113. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/exceptions/prompts.py +0 -0
  114. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/exceptions/questions.py +0 -0
  115. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/AnthropicService.py +0 -0
  116. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/AzureAI.py +0 -0
  117. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/DeepInfraService.py +0 -0
  118. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/GoogleService.py +0 -0
  119. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/GroqService.py +0 -0
  120. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/InferenceServiceABC.py +0 -0
  121. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/MistralAIService.py +0 -0
  122. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/OllamaService.py +0 -0
  123. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/OpenAIService.py +0 -0
  124. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/TestService.py +0 -0
  125. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/TogetherAIService.py +0 -0
  126. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/__init__.py +0 -0
  127. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/rate_limits_cache.py +0 -0
  128. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/registry.py +0 -0
  129. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/inference_services/write_available.py +0 -0
  130. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/Answers.py +0 -0
  131. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/__init__.py +0 -0
  132. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/buckets/BucketCollection.py +0 -0
  133. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/buckets/ModelBuckets.py +0 -0
  134. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/buckets/TokenBucket.py +0 -0
  135. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/interviews/InterviewStatistic.py +0 -0
  136. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/interviews/InterviewStatisticsCollection.py +0 -0
  137. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/interviews/InterviewStatusDictionary.py +0 -0
  138. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/interviews/InterviewStatusLog.py +0 -0
  139. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/interviews/interview_status_enum.py +0 -0
  140. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/runners/JobsRunnerStatus.py +0 -0
  141. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/runners/JobsRunnerStatusData.py +0 -0
  142. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/tasks/QuestionTaskCreator.py +0 -0
  143. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/tasks/TaskCreators.py +0 -0
  144. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/tasks/TaskStatusLog.py +0 -0
  145. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/tasks/task_status_enum.py +0 -0
  146. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/tokens/InterviewTokenUsage.py +0 -0
  147. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/jobs/tokens/TokenUsage.py +0 -0
  148. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/ModelList.py +0 -0
  149. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/RegisterLanguageModelsMeta.py +0 -0
  150. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/fake_openai_call.py +0 -0
  151. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/fake_openai_service.py +0 -0
  152. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/registry.py +0 -0
  153. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/repair.py +0 -0
  154. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/unused/ReplicateBase.py +0 -0
  155. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/language_models/utilities.py +0 -0
  156. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/notebooks/Notebook.py +0 -0
  157. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/notebooks/__init__.py +0 -0
  158. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/prompts/__init__.py +0 -0
  159. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/AnswerValidatorMixin.py +0 -0
  160. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionBaseGenMixin.py +0 -0
  161. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionBudget.py +0 -0
  162. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionCheckBox.py +0 -0
  163. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionExtract.py +0 -0
  164. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionList.py +0 -0
  165. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionMultipleChoice.py +0 -0
  166. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionNumerical.py +0 -0
  167. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/QuestionRank.py +0 -0
  168. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/Quick.py +0 -0
  169. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/RegisterQuestionsMeta.py +0 -0
  170. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/ResponseValidatorABC.py +0 -0
  171. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/SimpleAskMixin.py +0 -0
  172. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/__init__.py +0 -0
  173. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/compose_questions.py +0 -0
  174. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/decorators.py +0 -0
  175. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/derived/QuestionLikertFive.py +0 -0
  176. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/derived/QuestionLinearScale.py +0 -0
  177. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/derived/QuestionTopK.py +0 -0
  178. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/derived/QuestionYesNo.py +0 -0
  179. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/derived/__init__.py +0 -0
  180. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/prompt_templates/question_budget.jinja +0 -0
  181. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/prompt_templates/question_checkbox.jinja +0 -0
  182. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/prompt_templates/question_extract.jinja +0 -0
  183. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/prompt_templates/question_free_text.jinja +0 -0
  184. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/prompt_templates/question_linear_scale.jinja +0 -0
  185. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/prompt_templates/question_list.jinja +0 -0
  186. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/prompt_templates/question_multiple_choice.jinja +0 -0
  187. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/prompt_templates/question_numerical.jinja +0 -0
  188. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/question_registry.py +0 -0
  189. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/settings.py +0 -0
  190. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/__init__.py +0 -0
  191. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/budget/__init__.py +0 -0
  192. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/budget/answering_instructions.jinja +0 -0
  193. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/budget/question_presentation.jinja +0 -0
  194. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/checkbox/__init__.py +0 -0
  195. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/checkbox/answering_instructions.jinja +0 -0
  196. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/checkbox/question_presentation.jinja +0 -0
  197. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/extract/__init__.py +0 -0
  198. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/extract/answering_instructions.jinja +0 -0
  199. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/extract/question_presentation.jinja +0 -0
  200. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/free_text/__init__.py +0 -0
  201. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/free_text/answering_instructions.jinja +0 -0
  202. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/free_text/question_presentation.jinja +0 -0
  203. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/likert_five/__init__.py +0 -0
  204. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/likert_five/answering_instructions.jinja +0 -0
  205. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/likert_five/question_presentation.jinja +0 -0
  206. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/linear_scale/__init__.py +0 -0
  207. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/linear_scale/answering_instructions.jinja +0 -0
  208. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/linear_scale/question_presentation.jinja +0 -0
  209. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/list/__init__.py +0 -0
  210. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/list/answering_instructions.jinja +0 -0
  211. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/list/question_presentation.jinja +0 -0
  212. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/multiple_choice/__init__.py +0 -0
  213. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/multiple_choice/answering_instructions.jinja +0 -0
  214. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/multiple_choice/html.jinja +0 -0
  215. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/multiple_choice/question_presentation.jinja +0 -0
  216. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/numerical/__init__.py +0 -0
  217. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/numerical/answering_instructions.jinja +0 -0
  218. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/numerical/question_presentation.jinja +0 -0
  219. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/rank/__init__.py +0 -0
  220. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/rank/answering_instructions.jinja +0 -0
  221. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/rank/question_presentation.jinja +0 -0
  222. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/top_k/__init__.py +0 -0
  223. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/top_k/answering_instructions.jinja +0 -0
  224. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/top_k/question_presentation.jinja +0 -0
  225. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/yes_no/__init__.py +0 -0
  226. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/yes_no/answering_instructions.jinja +0 -0
  227. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/questions/templates/yes_no/question_presentation.jinja +0 -0
  228. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/Dataset.py +0 -0
  229. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/DatasetTree.py +0 -0
  230. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/ResultsExportMixin.py +0 -0
  231. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/ResultsFetchMixin.py +0 -0
  232. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/ResultsGGMixin.py +0 -0
  233. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/ResultsToolsMixin.py +0 -0
  234. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/__init__.py +0 -0
  235. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/results/tree_explore.py +0 -0
  236. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/scenarios/ScenarioListExportMixin.py +0 -0
  237. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/scenarios/ScenarioListPdfMixin.py +0 -0
  238. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/shared.py +0 -0
  239. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/study/ObjectEntry.py +0 -0
  240. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/study/ProofOfWork.py +0 -0
  241. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/study/SnapShot.py +0 -0
  242. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/study/Study.py +0 -0
  243. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/study/__init__.py +0 -0
  244. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/DAG.py +0 -0
  245. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/Memory.py +0 -0
  246. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/MemoryPlan.py +0 -0
  247. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/RuleCollection.py +0 -0
  248. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/SurveyCSS.py +0 -0
  249. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/SurveyExportMixin.py +0 -0
  250. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/SurveyFlowVisualizationMixin.py +0 -0
  251. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/SurveyQualtricsImport.py +0 -0
  252. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/__init__.py +0 -0
  253. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/base.py +0 -0
  254. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/descriptors.py +0 -0
  255. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/instructions/ChangeInstruction.py +0 -0
  256. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/instructions/Instruction.py +0 -0
  257. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/instructions/InstructionCollection.py +0 -0
  258. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/surveys/instructions/__init__.py +0 -0
  259. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/base.html +0 -0
  260. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/exceptions_by_model.html +0 -0
  261. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/exceptions_by_question_name.html +0 -0
  262. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/exceptions_by_type.html +0 -0
  263. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/interview_details.html +0 -0
  264. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/interviews.html +0 -0
  265. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/overview.html +0 -0
  266. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/performance_plot.html +0 -0
  267. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/report.css +0 -0
  268. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/report.html +0 -0
  269. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/templates/error_reporting/report.js +0 -0
  270. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/tools/__init__.py +0 -0
  271. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/tools/clusters.py +0 -0
  272. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/tools/embeddings.py +0 -0
  273. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/tools/embeddings_plotting.py +0 -0
  274. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/tools/plotting.py +0 -0
  275. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/tools/summarize.py +0 -0
  276. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/SystemInfo.py +0 -0
  277. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/__init__.py +0 -0
  278. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/ast_utilities.py +0 -0
  279. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/data/Registry.py +0 -0
  280. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/data/__init__.py +0 -0
  281. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/data/scooter_results.json +0 -0
  282. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/decorators.py +0 -0
  283. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/gcp_bucket/__init__.py +0 -0
  284. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/gcp_bucket/cloud_storage.py +0 -0
  285. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/interface.py +0 -0
  286. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/repair_functions.py +0 -0
  287. {edsl-0.1.36.dev5 → edsl-0.1.37}/edsl/utilities/restricted_python.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.36.dev5
3
+ Version: 0.1.37
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
@@ -27,6 +27,7 @@ from edsl.questions import QuestionTopK
27
27
 
28
28
  from edsl.scenarios import Scenario
29
29
  from edsl.scenarios import ScenarioList
30
+ from edsl.scenarios.FileStore import FileStore
30
31
 
31
32
  # from edsl.utilities.interface import print_dict_with_rich
32
33
  from edsl.surveys.Survey import Survey
@@ -0,0 +1 @@
1
+ __version__ = "0.1.37"
@@ -4,14 +4,23 @@ from __future__ import annotations
4
4
  import copy
5
5
  import inspect
6
6
  import types
7
- from typing import Callable, Optional, Union, Any
7
+ from typing import Callable, Optional, Union, Any, TYPE_CHECKING
8
+
9
+ if TYPE_CHECKING:
10
+ from edsl import Cache, Survey, Scenario
11
+ from edsl.language_models import LanguageModel
12
+ from edsl.surveys.MemoryPlan import MemoryPlan
13
+ from edsl.questions import QuestionBase
14
+ from edsl.agents.Invigilator import InvigilatorBase
15
+
8
16
  from uuid import uuid4
9
- from edsl.Base import Base
10
17
 
18
+ from edsl.Base import Base
11
19
  from edsl.prompts import Prompt
12
20
  from edsl.exceptions import QuestionScenarioRenderError
13
21
 
14
22
  from edsl.exceptions.agents import (
23
+ AgentErrors,
15
24
  AgentCombinationError,
16
25
  AgentDirectAnswerFunctionError,
17
26
  AgentDynamicTraitsFunctionError,
@@ -33,7 +42,9 @@ from edsl.utilities.restricted_python import create_restricted_function
33
42
 
34
43
 
35
44
  class Agent(Base):
36
- """An Agent that can answer questions."""
45
+ """An class representing an agent that can answer questions."""
46
+
47
+ __doc__ = "https://docs.expectedparrot.com/en/latest/agents.html"
37
48
 
38
49
  default_instruction = """You are answering questions as if you were a human. Do not break character."""
39
50
 
@@ -148,9 +159,10 @@ class Agent(Base):
148
159
  self.current_question = None
149
160
 
150
161
  if traits_presentation_template is not None:
162
+ self._traits_presentation_template = traits_presentation_template
151
163
  self.traits_presentation_template = traits_presentation_template
152
164
  else:
153
- self.traits_presentation_template = """Your traits: {{ traits }}"""
165
+ self.traits_presentation_template = "Your traits: {{traits}}"
154
166
 
155
167
  @property
156
168
  def agent_persona(self) -> Prompt:
@@ -181,13 +193,23 @@ class Agent(Base):
181
193
  """Check whether dynamic trait function is valid.
182
194
 
183
195
  This checks whether the dynamic traits function is valid.
196
+
197
+ >>> def f(question): return {"age": 10, "hair": "brown", "height": 5.5}
198
+ >>> a = Agent(dynamic_traits_function = f)
199
+ >>> a._check_dynamic_traits_function()
200
+
201
+ >>> def g(question, poo): return {"age": 10, "hair": "brown", "height": 5.5}
202
+ >>> a = Agent(dynamic_traits_function = g)
203
+ Traceback (most recent call last):
204
+ ...
205
+ edsl.exceptions.agents.AgentDynamicTraitsFunctionError: ...
184
206
  """
185
207
  if self.has_dynamic_traits_function:
186
208
  sig = inspect.signature(self.dynamic_traits_function)
187
209
  if "question" in sig.parameters:
188
210
  if len(sig.parameters) > 1:
189
211
  raise AgentDynamicTraitsFunctionError(
190
- f"The dynamic traits function {self.dynamic_traits_function} has too many parameters. It should only have one parameter: 'question'."
212
+ message=f"The dynamic traits function {self.dynamic_traits_function} has too many parameters. It should only have one parameter: 'question'."
191
213
  )
192
214
  else:
193
215
  if len(sig.parameters) > 0:
@@ -221,7 +243,38 @@ class Agent(Base):
221
243
  else:
222
244
  return self._traits
223
245
 
224
- def rename(self, old_name: str, new_name: str) -> Agent:
246
+ def rename(
247
+ self, old_name_or_dict: Union[str, dict], new_name: Optional[str] = None
248
+ ) -> Agent:
249
+ """Rename a trait.
250
+
251
+ Example usage:
252
+
253
+ >>> a = Agent(traits = {"age": 10, "hair": "brown", "height": 5.5})
254
+ >>> a.rename("age", "years") == Agent(traits = {'years': 10, 'hair': 'brown', 'height': 5.5})
255
+ True
256
+
257
+ >>> a.rename({'years': 'smage'})
258
+ Agent(traits = {'hair': 'brown', 'height': 5.5, 'smage': 10})
259
+
260
+ """
261
+ if isinstance(old_name_or_dict, dict) and new_name is None:
262
+ for old_name, new_name in old_name_or_dict.items():
263
+ self = self._rename(old_name, new_name)
264
+ return self
265
+
266
+ if isinstance(old_name_or_dict, dict) and new_name:
267
+ raise AgentErrors(
268
+ f"You passed a dict: {old_name_or_dict} and a new name: {new_name}. You should pass only a dict."
269
+ )
270
+
271
+ if isinstance(old_name_or_dict, str):
272
+ self._rename(old_name_or_dict, new_name)
273
+ return self
274
+
275
+ raise AgentErrors("Something is not right with Agent renaming")
276
+
277
+ def _rename(self, old_name: str, new_name: str) -> Agent:
225
278
  """Rename a trait.
226
279
 
227
280
  Example usage:
@@ -267,8 +320,11 @@ class Agent(Base):
267
320
  translate_response: bool = False,
268
321
  ) -> None:
269
322
  """Add a method to the agent that can answer a particular question type.
323
+ https://docs.expectedparrot.com/en/latest/agents.html#agent-direct-answering-methods
270
324
 
271
325
  :param method: A method that can answer a question directly.
326
+ :param validate_response: Whether to validate the response.
327
+ :param translate_response: Whether to translate the response.
272
328
 
273
329
  Example usage:
274
330
 
@@ -304,10 +360,10 @@ class Agent(Base):
304
360
  question: "QuestionBase",
305
361
  cache: "Cache",
306
362
  survey: Optional["Survey"] = None,
307
- scenario: Optional[Scenario] = None,
308
- model: Optional[LanguageModel] = None,
363
+ scenario: Optional["Scenario"] = None,
364
+ model: Optional["LanguageModel"] = None,
309
365
  debug: bool = False,
310
- memory_plan: Optional[MemoryPlan] = None,
366
+ memory_plan: Optional["MemoryPlan"] = None,
311
367
  current_answers: Optional[dict] = None,
312
368
  iteration: int = 1,
313
369
  sidecar_model=None,
@@ -354,13 +410,13 @@ class Agent(Base):
354
410
  async def async_answer_question(
355
411
  self,
356
412
  *,
357
- question: "QuestionBase",
358
- cache: "Cache",
359
- scenario: Optional["Scenario"] = None,
360
- survey: Optional["Survey"] = None,
361
- model: Optional["LanguageModel"] = None,
413
+ question: QuestionBase,
414
+ cache: Cache,
415
+ scenario: Optional[Scenario] = None,
416
+ survey: Optional[Survey] = None,
417
+ model: Optional[LanguageModel] = None,
362
418
  debug: bool = False,
363
- memory_plan: Optional["MemoryPlan"] = None,
419
+ memory_plan: Optional[MemoryPlan] = None,
364
420
  current_answers: Optional[dict] = None,
365
421
  iteration: int = 0,
366
422
  ) -> AgentResponseDict:
@@ -404,13 +460,13 @@ class Agent(Base):
404
460
 
405
461
  def _create_invigilator(
406
462
  self,
407
- question: "QuestionBase",
408
- cache: Optional["Cache"] = None,
409
- scenario: Optional["Scenario"] = None,
410
- model: Optional["LanguageModel"] = None,
411
- survey: Optional["Survey"] = None,
463
+ question: QuestionBase,
464
+ cache: Optional[Cache] = None,
465
+ scenario: Optional[Scenario] = None,
466
+ model: Optional[LanguageModel] = None,
467
+ survey: Optional[Survey] = None,
412
468
  debug: bool = False,
413
- memory_plan: Optional["MemoryPlan"] = None,
469
+ memory_plan: Optional[MemoryPlan] = None,
414
470
  current_answers: Optional[dict] = None,
415
471
  iteration: int = 0,
416
472
  sidecar_model=None,
@@ -493,9 +549,6 @@ class Agent(Base):
493
549
 
494
550
  return Agent(traits={trait: self.traits[trait] for trait in traits_to_select})
495
551
 
496
- ################
497
- # Dunder Methods
498
- ################
499
552
  def __add__(self, other_agent: Optional[Agent] = None) -> Agent:
500
553
  """
501
554
  Combine two agents by joining their traits.
@@ -512,6 +565,7 @@ class Agent(Base):
512
565
  Traceback (most recent call last):
513
566
  ...
514
567
  edsl.exceptions.agents.AgentCombinationError: The agents have overlapping traits: {'age'}.
568
+ ...
515
569
  """
516
570
  if other_agent is None:
517
571
  return self
@@ -540,12 +594,12 @@ class Agent(Base):
540
594
 
541
595
  def __getattr__(self, name):
542
596
  # This will be called only if 'name' is not found in the usual places
543
- # breakpoint()
544
597
  if name == "has_dynamic_traits_function":
545
598
  return self.has_dynamic_traits_function
546
599
 
547
600
  if name in self._traits:
548
601
  return self._traits[name]
602
+
549
603
  raise AttributeError(
550
604
  f"'{type(self).__name__}' object has no attribute '{name}'"
551
605
  )
@@ -598,6 +652,7 @@ class Agent(Base):
598
652
  for k, v in self.__dict__.items()
599
653
  if k.startswith("_")
600
654
  }
655
+
601
656
  if hasattr(self, "set_instructions"):
602
657
  if not self.set_instructions:
603
658
  raw_data.pop("instruction")
@@ -614,16 +669,14 @@ class Agent(Base):
614
669
  if dynamic_traits_func:
615
670
  func = inspect.getsource(dynamic_traits_func)
616
671
  raw_data["dynamic_traits_function_source_code"] = func
617
- raw_data["dynamic_traits_function_name"] = (
618
- self.dynamic_traits_function_name
619
- )
672
+ raw_data[
673
+ "dynamic_traits_function_name"
674
+ ] = self.dynamic_traits_function_name
620
675
  if hasattr(self, "answer_question_directly"):
621
676
  raw_data.pop(
622
677
  "answer_question_directly", None
623
678
  ) # in case answer_question_directly will appear with _ in self.__dict__
624
679
  answer_question_directly_func = self.answer_question_directly
625
- # print(answer_question_directly_func)
626
- # print(type(answer_question_directly_func), flush=True)
627
680
 
628
681
  if (
629
682
  answer_question_directly_func
@@ -632,9 +685,9 @@ class Agent(Base):
632
685
  raw_data["answer_question_directly_source_code"] = inspect.getsource(
633
686
  answer_question_directly_func
634
687
  )
635
- raw_data["answer_question_directly_function_name"] = (
636
- self.answer_question_directly_function_name
637
- )
688
+ raw_data[
689
+ "answer_question_directly_function_name"
690
+ ] = self.answer_question_directly_function_name
638
691
 
639
692
  return raw_data
640
693
 
@@ -644,12 +697,12 @@ class Agent(Base):
644
697
  return dict_hash(self._to_dict())
645
698
 
646
699
  def _to_dict(self) -> dict[str, Union[dict, bool]]:
647
- """Serialize to a dictionary."""
700
+ """Serialize to a dictionary without EDSL info"""
648
701
  return self.data
649
702
 
650
703
  @add_edsl_version
651
704
  def to_dict(self) -> dict[str, Union[dict, bool]]:
652
- """Serialize to a dictionary.
705
+ """Serialize to a dictionary with EDSL info.
653
706
 
654
707
  Example usage:
655
708
 
@@ -672,10 +725,6 @@ class Agent(Base):
672
725
  """
673
726
  return cls(**agent_dict)
674
727
 
675
- ################
676
- # DISPLAY Methods
677
- ################
678
-
679
728
  def _table(self) -> tuple[dict, list]:
680
729
  """Prepare generic table data."""
681
730
  table_data = []
@@ -691,14 +740,16 @@ class Agent(Base):
691
740
  return self
692
741
 
693
742
  if isinstance(trait_name_or_dict, dict) and value:
694
- raise ValueError(f"You passed a dict: {trait_name_or_dict}")
743
+ raise AgentErrors(
744
+ f"You passed a dict: {trait_name_or_dict} and a value: {value}. You should pass only a dict."
745
+ )
695
746
 
696
747
  if isinstance(trait_name_or_dict, str):
697
748
  trait = trait_name_or_dict
698
749
  self.traits[trait] = value
699
750
  return self
700
751
 
701
- raise Exception("Something is not right with adding")
752
+ raise AgentErrors("Something is not right with adding a trait to an Agent")
702
753
 
703
754
  def remove_trait(self, trait: str) -> Agent:
704
755
  """Remove a trait from the agent.
@@ -125,7 +125,7 @@ class AgentList(UserList, Base):
125
125
  return list(d.keys())
126
126
 
127
127
  @classmethod
128
- def from_csv(cls, file_path: str):
128
+ def from_csv(cls, file_path: str, name_field: Optional[str] = None):
129
129
  """Load AgentList from a CSV file.
130
130
 
131
131
  >>> import csv
@@ -137,9 +137,13 @@ class AgentList(UserList, Base):
137
137
  >>> al = AgentList.from_csv('/tmp/agents.csv')
138
138
  >>> al
139
139
  AgentList([Agent(traits = {'age': '22', 'hair': 'brown', 'height': '5.5'})])
140
+ >>> al = AgentList.from_csv('/tmp/agents.csv', name_field='hair')
141
+ >>> al
142
+ AgentList([Agent(name = \"""brown\""", traits = {'age': '22', 'height': '5.5'})])
140
143
  >>> os.remove('/tmp/agents.csv')
141
144
 
142
145
  :param file_path: The path to the CSV file.
146
+ :param name_field: The name of the field to use as the agent name.
143
147
  """
144
148
  from edsl.agents.Agent import Agent
145
149
 
@@ -147,7 +151,16 @@ class AgentList(UserList, Base):
147
151
  with open(file_path, "r") as f:
148
152
  reader = csv.DictReader(f)
149
153
  for row in reader:
150
- agent_list.append(Agent(row))
154
+ if "name" in row:
155
+ import warnings
156
+
157
+ warnings.warn("Using 'name' field in the CSV for the Agent name")
158
+ name_field = "name"
159
+ if name_field is not None:
160
+ agent_name = row.pop(name_field)
161
+ agent_list.append(Agent(traits=row, name=agent_name))
162
+ else:
163
+ agent_list.append(Agent(traits=row))
151
164
  return cls(agent_list)
152
165
 
153
166
  def translate_traits(self, values_codebook: dict[str, str]):
@@ -16,6 +16,8 @@ from edsl.language_models.LanguageModel import LanguageModel
16
16
  from edsl.data_transfer_models import EDSLResultObjectInput
17
17
  from edsl.agents.PromptConstructor import PromptConstructor
18
18
 
19
+ from edsl.agents.prompt_helpers import PromptPlan
20
+
19
21
 
20
22
  class InvigilatorBase(ABC):
21
23
  """An invigiator (someone who administers an exam) is a class that is responsible for administering a question to an agent.
@@ -45,6 +47,7 @@ class InvigilatorBase(ABC):
45
47
  additional_prompt_data: Optional[dict] = None,
46
48
  sidecar_model: Optional[LanguageModel] = None,
47
49
  raise_validation_errors: Optional[bool] = True,
50
+ prompt_plan: Optional["PromptPlan"] = None,
48
51
  ):
49
52
  """Initialize a new Invigilator."""
50
53
  self.agent = agent
@@ -59,6 +62,10 @@ class InvigilatorBase(ABC):
59
62
  self.sidecar_model = sidecar_model
60
63
  self.survey = survey
61
64
  self.raise_validation_errors = raise_validation_errors
65
+ if prompt_plan is None:
66
+ self.prompt_plan = PromptPlan()
67
+ else:
68
+ self.prompt_plan = prompt_plan
62
69
 
63
70
  self.raw_model_response = (
64
71
  None # placeholder for the raw response from the model
@@ -67,7 +74,7 @@ class InvigilatorBase(ABC):
67
74
  @property
68
75
  def prompt_constructor(self) -> PromptConstructor:
69
76
  """Return the prompt constructor."""
70
- return PromptConstructor(self)
77
+ return PromptConstructor(self, prompt_plan=self.prompt_plan)
71
78
 
72
79
  def to_dict(self):
73
80
  attributes = [
@@ -115,7 +122,11 @@ class InvigilatorBase(ABC):
115
122
  iteration = data["iteration"]
116
123
  additional_prompt_data = data["additional_prompt_data"]
117
124
  cache = Cache.from_dict(data["cache"])
118
- sidecar_model = LanguageModel.from_dict(data["sidecar_model"])
125
+
126
+ if data["sidecar_model"] is None:
127
+ sidecar_model = None
128
+ else:
129
+ sidecar_model = LanguageModel.from_dict(data["sidecar_model"])
119
130
 
120
131
  return cls(
121
132
  agent=agent,
@@ -225,24 +236,6 @@ class InvigilatorBase(ABC):
225
236
  from edsl import Model
226
237
 
227
238
  model = Model("test", canned_response="SPAM!")
228
- # class TestLanguageModelGood(LanguageModel):
229
- # """A test language model."""
230
-
231
- # _model_ = "test"
232
- # _parameters_ = {"temperature": 0.5}
233
- # _inference_service_ = InferenceServiceType.TEST.value
234
-
235
- # async def async_execute_model_call(
236
- # self, user_prompt: str, system_prompt: str
237
- # ) -> dict[str, Any]:
238
- # await asyncio.sleep(0.1)
239
- # if hasattr(self, "throw_an_exception"):
240
- # raise Exception("Error!")
241
- # return {"message": """{"answer": "SPAM!"}"""}
242
-
243
- # def parse_response(self, raw_response: dict[str, Any]) -> str:
244
- # """Parse the response from the model."""
245
- # return raw_response["message"]
246
239
 
247
240
  if throw_an_exception:
248
241
  model.throw_an_exception = True
@@ -252,11 +245,8 @@ class InvigilatorBase(ABC):
252
245
 
253
246
  if not survey:
254
247
  survey = Survey.example()
255
- # if question:
256
- # need to have the focal question name in the list of names
257
- # survey._questions[0].question_name = question.question_name
258
- # survey.add_question(question)
259
- if question:
248
+
249
+ if question not in survey.questions and question is not None:
260
250
  survey.add_question(question)
261
251
 
262
252
  question = question or survey.questions[0]