edsl 0.1.28__tar.gz → 0.1.29__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.
- {edsl-0.1.28 → edsl-0.1.29}/PKG-INFO +11 -10
- {edsl-0.1.28 → edsl-0.1.29}/README.md +10 -10
- edsl-0.1.29/edsl/Base.py +288 -0
- edsl-0.1.29/edsl/__init__.py +42 -0
- edsl-0.1.29/edsl/__version__.py +1 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/agents/Agent.py +77 -41
- {edsl-0.1.28 → edsl-0.1.29}/edsl/agents/AgentList.py +35 -6
- {edsl-0.1.28 → edsl-0.1.29}/edsl/agents/Invigilator.py +19 -1
- {edsl-0.1.28 → edsl-0.1.29}/edsl/agents/InvigilatorBase.py +15 -10
- edsl-0.1.29/edsl/agents/PromptConstructionMixin.py +376 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/agents/descriptors.py +2 -1
- {edsl-0.1.28/edsl → edsl-0.1.29/edsl/base}/Base.py +2 -1
- {edsl-0.1.28 → edsl-0.1.29}/edsl/config.py +2 -1
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/InputData.py +39 -8
- {edsl-0.1.28 → edsl-0.1.29}/edsl/coop/coop.py +188 -151
- edsl-0.1.29/edsl/coop/utils.py +123 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/data/Cache.py +19 -5
- {edsl-0.1.28 → edsl-0.1.29}/edsl/data/SQLiteDict.py +11 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/Answers.py +15 -1
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/Jobs.py +92 -47
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/buckets/ModelBuckets.py +4 -2
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/buckets/TokenBucket.py +1 -2
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/Interview.py +3 -9
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/InterviewStatusMixin.py +3 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/InterviewTaskBuildingMixin.py +15 -10
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/runners/JobsRunnerAsyncio.py +21 -25
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/tasks/TaskHistory.py +4 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/language_models/LanguageModel.py +5 -11
- {edsl-0.1.28 → edsl-0.1.29}/edsl/language_models/ModelList.py +3 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/language_models/repair.py +8 -7
- {edsl-0.1.28 → edsl-0.1.29}/edsl/notebooks/Notebook.py +40 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/Prompt.py +31 -19
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionBase.py +38 -13
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionBudget.py +5 -6
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionCheckBox.py +7 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionExtract.py +5 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionFreeText.py +3 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionFunctional.py +0 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionList.py +3 -4
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionMultipleChoice.py +16 -8
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionNumerical.py +4 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/QuestionRank.py +5 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/__init__.py +4 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/descriptors.py +4 -2
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/question_registry.py +20 -31
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/settings.py +1 -1
- {edsl-0.1.28 → edsl-0.1.29}/edsl/results/Dataset.py +31 -0
- edsl-0.1.28/edsl/results/ResultsExportMixin.py → edsl-0.1.29/edsl/results/DatasetExportMixin.py +25 -90
- {edsl-0.1.28 → edsl-0.1.29}/edsl/results/Result.py +22 -74
- {edsl-0.1.28 → edsl-0.1.29}/edsl/results/Results.py +105 -67
- {edsl-0.1.28 → edsl-0.1.29}/edsl/results/ResultsDBMixin.py +7 -3
- edsl-0.1.29/edsl/results/ResultsExportMixin.py +43 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/results/ResultsGGMixin.py +3 -3
- {edsl-0.1.28 → edsl-0.1.29}/edsl/results/ResultsToolsMixin.py +5 -5
- edsl-0.1.29/edsl/scenarios/FileStore.py +140 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/scenarios/Scenario.py +5 -6
- {edsl-0.1.28 → edsl-0.1.29}/edsl/scenarios/ScenarioList.py +44 -15
- edsl-0.1.29/edsl/scenarios/ScenarioListExportMixin.py +32 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/scenarios/ScenarioListPdfMixin.py +2 -1
- edsl-0.1.29/edsl/scenarios/__init__.py +2 -0
- edsl-0.1.29/edsl/study/ObjectEntry.py +173 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/study/ProofOfWork.py +5 -2
- {edsl-0.1.28 → edsl-0.1.29}/edsl/study/SnapShot.py +4 -8
- {edsl-0.1.28 → edsl-0.1.29}/edsl/study/Study.py +21 -14
- {edsl-0.1.28 → edsl-0.1.29}/edsl/study/__init__.py +2 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/MemoryPlan.py +11 -4
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/Survey.py +46 -7
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/SurveyExportMixin.py +4 -2
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/SurveyFlowVisualizationMixin.py +6 -4
- {edsl-0.1.28 → edsl-0.1.29}/edsl/tools/plotting.py +4 -2
- edsl-0.1.29/edsl/utilities/__init__.py +22 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/interface.py +66 -45
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/utilities.py +11 -13
- {edsl-0.1.28 → edsl-0.1.29}/pyproject.toml +1 -4
- edsl-0.1.28/edsl/__init__.py +0 -42
- edsl-0.1.28/edsl/__version__.py +0 -1
- edsl-0.1.28/edsl/agents/PromptConstructionMixin.py +0 -134
- edsl-0.1.28/edsl/coop/utils.py +0 -155
- edsl-0.1.28/edsl/scenarios/__init__.py +0 -1
- edsl-0.1.28/edsl/study/ObjectEntry.py +0 -97
- edsl-0.1.28/edsl/utilities/__init__.py +0 -22
- {edsl-0.1.28 → edsl-0.1.29}/LICENSE +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/BaseDiff.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/agents/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/AgentConstructionMixin.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/Conjure.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/InputDataCSV.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/InputDataMixinQuestionStats.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/InputDataPyRead.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/InputDataSPSS.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/InputDataStata.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/QuestionOptionMixin.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/QuestionTypeMixin.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/RawQuestion.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/SurveyResponses.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/examples/placeholder.txt +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/naming_utilities.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conjure/utilities.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conversation/Conversation.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conversation/car_buying.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conversation/mug_negotiation.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/conversation/next_speaker_utilities.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/coop/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/data/CacheEntry.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/data/CacheHandler.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/data/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/data/orm.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/data_transfer_models.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/enums.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/agents.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/configuration.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/coop.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/data.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/general.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/jobs.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/language_models.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/prompts.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/questions.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/results.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/exceptions/surveys.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/AnthropicService.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/DeepInfraService.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/GoogleService.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/InferenceServiceABC.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/InferenceServicesCollection.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/OpenAIService.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/models_available_cache.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/rate_limits_cache.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/registry.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/inference_services/write_available.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/buckets/BucketCollection.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/InterviewStatistic.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/InterviewStatisticsCollection.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/InterviewStatusDictionary.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/InterviewStatusLog.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/ReportErrors.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/interview_exception_tracking.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/interview_status_enum.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/interviews/retry_management.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/runners/JobsRunnerStatusData.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/runners/JobsRunnerStatusMixin.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/tasks/QuestionTaskCreator.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/tasks/TaskCreators.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/tasks/TaskStatusLog.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/tasks/task_management.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/tasks/task_status_enum.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/tokens/InterviewTokenUsage.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/jobs/tokens/TokenUsage.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/language_models/RegisterLanguageModelsMeta.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/language_models/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/language_models/registry.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/language_models/unused/ReplicateBase.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/notebooks/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/QuestionInstructionsBase.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/agent_instructions.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/agent_persona.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/question_budget.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/question_checkbox.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/question_extract.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/question_freetext.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/question_linear_scale.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/question_list.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/question_multiple_choice.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/question_numerical.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/library/question_rank.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/prompt_config.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/prompts/registry.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/AnswerValidatorMixin.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/RegisterQuestionsMeta.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/SimpleAskMixin.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/compose_questions.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/derived/QuestionLikertFive.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/derived/QuestionLinearScale.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/derived/QuestionTopK.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/derived/QuestionYesNo.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/questions/derived/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/results/ResultsFetchMixin.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/results/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/scenarios/ScenarioHtmlMixin.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/scenarios/ScenarioImageMixin.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/shared.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/DAG.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/Memory.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/Rule.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/RuleCollection.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/SurveyCSS.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/base.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/surveys/descriptors.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/tools/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/tools/clusters.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/tools/embeddings.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/tools/embeddings_plotting.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/tools/summarize.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/SystemInfo.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/ast_utilities.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/data/Registry.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/data/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/data/scooter_results.json +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/decorators.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/gcp_bucket/__init__.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/gcp_bucket/cloud_storage.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/gcp_bucket/simple_example.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/edsl/utilities/repair_functions.py +0 -0
- {edsl-0.1.28 → edsl-0.1.29}/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.
|
3
|
+
Version: 0.1.29
|
4
4
|
Summary: Create and analyze LLM-based surveys
|
5
5
|
Home-page: https://www.expectedparrot.com/
|
6
6
|
License: MIT
|
@@ -57,15 +57,6 @@ The Expected Parrot Domain-Specific Language (EDSL) package lets you conduct com
|
|
57
57
|
- [LinkedIn](https://www.linkedin.com/company/expectedparrot/)
|
58
58
|
- [Blog](https://blog.expectedparrot.com)
|
59
59
|
|
60
|
-
## 💡 Contributions, feature requests & bugs
|
61
|
-
Interested in contributing? Want us to add a new feature? Found a bug for us to squash?
|
62
|
-
Please send us an email at [info@expectedparrot.com](mailto:info@expectedparrot.com) or message us at our [Discord channel](https://discord.com/invite/mxAYkjfy9m).
|
63
|
-
|
64
|
-
## 💻 Requirements
|
65
|
-
* EDSL is compatible with Python 3.9 - 3.12.
|
66
|
-
* API keys for large language models that you want to use, stored in a `.env` file.
|
67
|
-
See instructions on [storing API keys](https://docs.expectedparrot.com/en/latest/api_keys.html).
|
68
|
-
|
69
60
|
## 🌎 Hello, World!
|
70
61
|
A quick example:
|
71
62
|
|
@@ -96,3 +87,13 @@ Output:
|
|
96
87
|
│ Good │
|
97
88
|
└───────────────────┘
|
98
89
|
```
|
90
|
+
|
91
|
+
## 💻 Requirements
|
92
|
+
* EDSL is compatible with Python 3.9 - 3.12.
|
93
|
+
* API keys for large language models that you want to use, stored in a `.env` file.
|
94
|
+
See instructions on [storing API keys](https://docs.expectedparrot.com/en/latest/api_keys.html).
|
95
|
+
|
96
|
+
## 💡 Contributions, feature requests & bugs
|
97
|
+
Interested in contributing? Want us to add a new feature? Found a bug for us to squash?
|
98
|
+
Please send us an email at [info@expectedparrot.com](mailto:info@expectedparrot.com) or message us at our [Discord channel](https://discord.com/invite/mxAYkjfy9m).
|
99
|
+
|
@@ -14,15 +14,6 @@ The Expected Parrot Domain-Specific Language (EDSL) package lets you conduct com
|
|
14
14
|
- [LinkedIn](https://www.linkedin.com/company/expectedparrot/)
|
15
15
|
- [Blog](https://blog.expectedparrot.com)
|
16
16
|
|
17
|
-
## 💡 Contributions, feature requests & bugs
|
18
|
-
Interested in contributing? Want us to add a new feature? Found a bug for us to squash?
|
19
|
-
Please send us an email at [info@expectedparrot.com](mailto:info@expectedparrot.com) or message us at our [Discord channel](https://discord.com/invite/mxAYkjfy9m).
|
20
|
-
|
21
|
-
## 💻 Requirements
|
22
|
-
* EDSL is compatible with Python 3.9 - 3.12.
|
23
|
-
* API keys for large language models that you want to use, stored in a `.env` file.
|
24
|
-
See instructions on [storing API keys](https://docs.expectedparrot.com/en/latest/api_keys.html).
|
25
|
-
|
26
17
|
## 🌎 Hello, World!
|
27
18
|
A quick example:
|
28
19
|
|
@@ -52,4 +43,13 @@ Output:
|
|
52
43
|
┡━━━━━━━━━━━━━━━━━━━┩
|
53
44
|
│ Good │
|
54
45
|
└───────────────────┘
|
55
|
-
```
|
46
|
+
```
|
47
|
+
|
48
|
+
## 💻 Requirements
|
49
|
+
* EDSL is compatible with Python 3.9 - 3.12.
|
50
|
+
* API keys for large language models that you want to use, stored in a `.env` file.
|
51
|
+
See instructions on [storing API keys](https://docs.expectedparrot.com/en/latest/api_keys.html).
|
52
|
+
|
53
|
+
## 💡 Contributions, feature requests & bugs
|
54
|
+
Interested in contributing? Want us to add a new feature? Found a bug for us to squash?
|
55
|
+
Please send us an email at [info@expectedparrot.com](mailto:info@expectedparrot.com) or message us at our [Discord channel](https://discord.com/invite/mxAYkjfy9m).
|
edsl-0.1.29/edsl/Base.py
ADDED
@@ -0,0 +1,288 @@
|
|
1
|
+
"""Base class for all classes in the package. It provides rich printing and persistence of objects."""
|
2
|
+
|
3
|
+
from abc import ABC, abstractmethod, ABCMeta
|
4
|
+
import gzip
|
5
|
+
import io
|
6
|
+
import json
|
7
|
+
from typing import Any, Optional, Union
|
8
|
+
from uuid import UUID
|
9
|
+
|
10
|
+
|
11
|
+
class RichPrintingMixin:
|
12
|
+
"""Mixin for rich printing and persistence of objects."""
|
13
|
+
|
14
|
+
def _for_console(self):
|
15
|
+
"""Return a string representation of the object for console printing."""
|
16
|
+
from rich.console import Console
|
17
|
+
|
18
|
+
with io.StringIO() as buf:
|
19
|
+
console = Console(file=buf, record=True)
|
20
|
+
table = self.rich_print()
|
21
|
+
console.print(table)
|
22
|
+
return console.export_text()
|
23
|
+
|
24
|
+
def __str__(self):
|
25
|
+
"""Return a string representation of the object for console printing."""
|
26
|
+
return self._for_console()
|
27
|
+
|
28
|
+
def print(self):
|
29
|
+
"""Print the object to the console."""
|
30
|
+
from edsl.utilities.utilities import is_notebook
|
31
|
+
|
32
|
+
if is_notebook():
|
33
|
+
from IPython.display import display
|
34
|
+
|
35
|
+
display(self.rich_print())
|
36
|
+
else:
|
37
|
+
from rich.console import Console
|
38
|
+
|
39
|
+
console = Console()
|
40
|
+
console.print(self.rich_print())
|
41
|
+
|
42
|
+
|
43
|
+
class PersistenceMixin:
|
44
|
+
"""Mixin for saving and loading objects to and from files."""
|
45
|
+
|
46
|
+
def push(
|
47
|
+
self,
|
48
|
+
description: Optional[str] = None,
|
49
|
+
visibility: Optional[str] = "unlisted",
|
50
|
+
):
|
51
|
+
"""Post the object to coop."""
|
52
|
+
from edsl.coop import Coop
|
53
|
+
|
54
|
+
c = Coop()
|
55
|
+
return c.create(self, description, visibility)
|
56
|
+
|
57
|
+
@classmethod
|
58
|
+
def pull(cls, uuid: Optional[Union[str, UUID]] = None, url: Optional[str] = None):
|
59
|
+
"""Pull the object from coop."""
|
60
|
+
from edsl.coop import Coop
|
61
|
+
from edsl.coop.utils import ObjectRegistry
|
62
|
+
|
63
|
+
object_type = ObjectRegistry.get_object_type_by_edsl_class(cls)
|
64
|
+
coop = Coop()
|
65
|
+
return coop.get(uuid, url, object_type)
|
66
|
+
|
67
|
+
@classmethod
|
68
|
+
def delete(cls, uuid: Optional[Union[str, UUID]] = None, url: Optional[str] = None):
|
69
|
+
"""Delete the object from coop."""
|
70
|
+
from edsl.coop import Coop
|
71
|
+
|
72
|
+
coop = Coop()
|
73
|
+
return coop.delete(uuid, url)
|
74
|
+
|
75
|
+
@classmethod
|
76
|
+
def patch(
|
77
|
+
cls,
|
78
|
+
uuid: Optional[Union[str, UUID]] = None,
|
79
|
+
url: Optional[str] = None,
|
80
|
+
description: Optional[str] = None,
|
81
|
+
value: Optional[Any] = None,
|
82
|
+
visibility: Optional[str] = None,
|
83
|
+
):
|
84
|
+
"""
|
85
|
+
Patch an uploaded objects attributes.
|
86
|
+
- `description` changes the description of the object on Coop
|
87
|
+
- `value` changes the value of the object on Coop. **has to be an EDSL object**
|
88
|
+
- `visibility` changes the visibility of the object on Coop
|
89
|
+
"""
|
90
|
+
from edsl.coop import Coop
|
91
|
+
|
92
|
+
coop = Coop()
|
93
|
+
return coop.patch(uuid, url, description, value, visibility)
|
94
|
+
|
95
|
+
@classmethod
|
96
|
+
def search(cls, query):
|
97
|
+
"""Search for objects on coop."""
|
98
|
+
from edsl.coop import Coop
|
99
|
+
|
100
|
+
c = Coop()
|
101
|
+
return c.search(cls, query)
|
102
|
+
|
103
|
+
def save(self, filename, compress=True):
|
104
|
+
"""Save the object to a file as zippped JSON.
|
105
|
+
|
106
|
+
>>> obj.save("obj.json.gz")
|
107
|
+
|
108
|
+
"""
|
109
|
+
if filename.endswith("json.gz"):
|
110
|
+
import warnings
|
111
|
+
|
112
|
+
warnings.warn(
|
113
|
+
"Do not apply the file extensions. The filename should not end with 'json.gz'."
|
114
|
+
)
|
115
|
+
filename = filename[:-7]
|
116
|
+
if filename.endswith("json"):
|
117
|
+
filename = filename[:-4]
|
118
|
+
warnings.warn(
|
119
|
+
"Do not apply the file extensions. The filename should not end with 'json'."
|
120
|
+
)
|
121
|
+
|
122
|
+
if compress:
|
123
|
+
with gzip.open(filename + ".json.gz", "wb") as f:
|
124
|
+
f.write(json.dumps(self.to_dict()).encode("utf-8"))
|
125
|
+
else:
|
126
|
+
with open(filename + ".json", "w") as f:
|
127
|
+
f.write(json.dumps(self.to_dict()))
|
128
|
+
|
129
|
+
@staticmethod
|
130
|
+
def open_compressed_file(filename):
|
131
|
+
with gzip.open(filename, "rb") as f:
|
132
|
+
file_contents = f.read()
|
133
|
+
file_contents_decoded = file_contents.decode("utf-8")
|
134
|
+
d = json.loads(file_contents_decoded)
|
135
|
+
return d
|
136
|
+
|
137
|
+
@staticmethod
|
138
|
+
def open_regular_file(filename):
|
139
|
+
with open(filename, "r") as f:
|
140
|
+
d = json.loads(f.read())
|
141
|
+
return d
|
142
|
+
|
143
|
+
@classmethod
|
144
|
+
def load(cls, filename):
|
145
|
+
"""Load the object from a file.
|
146
|
+
|
147
|
+
>>> obj = cls.load("obj.json.gz")
|
148
|
+
|
149
|
+
"""
|
150
|
+
|
151
|
+
if filename.endswith("json.gz"):
|
152
|
+
d = cls.open_compressed_file(filename)
|
153
|
+
elif filename.endswith("json"):
|
154
|
+
d = cls.open_regular_file(filename)
|
155
|
+
else:
|
156
|
+
try:
|
157
|
+
d = cls.open_compressed_file(filename)
|
158
|
+
except:
|
159
|
+
d = cls.open_regular_file(filename)
|
160
|
+
finally:
|
161
|
+
raise ValueError("File must be a json or json.gz file")
|
162
|
+
|
163
|
+
return cls.from_dict(d)
|
164
|
+
|
165
|
+
|
166
|
+
class RegisterSubclassesMeta(ABCMeta):
|
167
|
+
"""Metaclass for registering subclasses."""
|
168
|
+
|
169
|
+
_registry = {}
|
170
|
+
|
171
|
+
def __init__(cls, name, bases, nmspc):
|
172
|
+
"""Register the class in the registry upon creation."""
|
173
|
+
super(RegisterSubclassesMeta, cls).__init__(name, bases, nmspc)
|
174
|
+
if cls.__name__ != "Base":
|
175
|
+
RegisterSubclassesMeta._registry[cls.__name__] = cls
|
176
|
+
|
177
|
+
@staticmethod
|
178
|
+
def get_registry():
|
179
|
+
"""Return the registry of subclasses."""
|
180
|
+
return dict(RegisterSubclassesMeta._registry)
|
181
|
+
|
182
|
+
|
183
|
+
class DiffMethodsMixin:
|
184
|
+
def __sub__(self, other):
|
185
|
+
"""Return the difference between two objects."""
|
186
|
+
from edsl.BaseDiff import BaseDiff
|
187
|
+
|
188
|
+
return BaseDiff(self, other)
|
189
|
+
|
190
|
+
|
191
|
+
class Base(
|
192
|
+
RichPrintingMixin,
|
193
|
+
PersistenceMixin,
|
194
|
+
DiffMethodsMixin,
|
195
|
+
ABC,
|
196
|
+
metaclass=RegisterSubclassesMeta,
|
197
|
+
):
|
198
|
+
"""Base class for all classes in the package."""
|
199
|
+
|
200
|
+
# def __getitem__(self, key):
|
201
|
+
# return getattr(self, key)
|
202
|
+
|
203
|
+
# @abstractmethod
|
204
|
+
# def _repr_html_(self) -> str:
|
205
|
+
# raise NotImplementedError("This method is not implemented yet.")
|
206
|
+
|
207
|
+
# @abstractmethod
|
208
|
+
# def _repr_(self) -> str:
|
209
|
+
# raise NotImplementedError("This method is not implemented yet.")
|
210
|
+
|
211
|
+
def keys(self):
|
212
|
+
"""Return the keys of the object."""
|
213
|
+
_keys = list(self.to_dict().keys())
|
214
|
+
if "edsl_version" in _keys:
|
215
|
+
_keys.remove("edsl_version")
|
216
|
+
if "edsl_class_name" in _keys:
|
217
|
+
_keys.remove("edsl_class_name")
|
218
|
+
return _keys
|
219
|
+
|
220
|
+
def values(self):
|
221
|
+
"""Return the values of the object."""
|
222
|
+
data = self.to_dict()
|
223
|
+
keys = self.keys()
|
224
|
+
return {data[key] for key in keys}
|
225
|
+
|
226
|
+
def _repr_html_(self):
|
227
|
+
from edsl.utilities.utilities import data_to_html
|
228
|
+
|
229
|
+
return data_to_html(self.to_dict())
|
230
|
+
|
231
|
+
# def html(self):
|
232
|
+
# html_string = self._repr_html_()
|
233
|
+
# import tempfile
|
234
|
+
# import webbrowser
|
235
|
+
|
236
|
+
# with tempfile.NamedTemporaryFile("w", delete=False, suffix=".html") as f:
|
237
|
+
# # print("Writing HTML to", f.name)
|
238
|
+
# f.write(html_string)
|
239
|
+
# webbrowser.open(f.name)
|
240
|
+
|
241
|
+
def __eq__(self, other):
|
242
|
+
"""Return whether two objects are equal."""
|
243
|
+
import inspect
|
244
|
+
|
245
|
+
if not isinstance(other, self.__class__):
|
246
|
+
return False
|
247
|
+
if "sort" in inspect.signature(self._to_dict).parameters:
|
248
|
+
return self._to_dict(sort=True) == other._to_dict(sort=True)
|
249
|
+
else:
|
250
|
+
return self._to_dict() == other._to_dict()
|
251
|
+
|
252
|
+
@abstractmethod
|
253
|
+
def example():
|
254
|
+
"""This method should be implemented by subclasses."""
|
255
|
+
raise NotImplementedError("This method is not implemented yet.")
|
256
|
+
|
257
|
+
@abstractmethod
|
258
|
+
def rich_print():
|
259
|
+
"""This method should be implemented by subclasses."""
|
260
|
+
raise NotImplementedError("This method is not implemented yet.")
|
261
|
+
|
262
|
+
@abstractmethod
|
263
|
+
def to_dict():
|
264
|
+
"""This method should be implemented by subclasses."""
|
265
|
+
raise NotImplementedError("This method is not implemented yet.")
|
266
|
+
|
267
|
+
@abstractmethod
|
268
|
+
def from_dict():
|
269
|
+
"""This method should be implemented by subclasses."""
|
270
|
+
raise NotImplementedError("This method is not implemented yet.")
|
271
|
+
|
272
|
+
@abstractmethod
|
273
|
+
def code():
|
274
|
+
"""This method should be implemented by subclasses."""
|
275
|
+
raise NotImplementedError("This method is not implemented yet.")
|
276
|
+
|
277
|
+
def show_methods(self, show_docstrings=True):
|
278
|
+
"""Show the methods of the object."""
|
279
|
+
public_methods_with_docstrings = [
|
280
|
+
(method, getattr(self, method).__doc__)
|
281
|
+
for method in dir(self)
|
282
|
+
if callable(getattr(self, method)) and not method.startswith("_")
|
283
|
+
]
|
284
|
+
if show_docstrings:
|
285
|
+
for method, documentation in public_methods_with_docstrings:
|
286
|
+
print(f"{method}: {documentation}")
|
287
|
+
else:
|
288
|
+
return [x[0] for x in public_methods_with_docstrings]
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import os
|
2
|
+
import time
|
3
|
+
|
4
|
+
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
5
|
+
ROOT_DIR = os.path.dirname(BASE_DIR)
|
6
|
+
|
7
|
+
from edsl.__version__ import __version__
|
8
|
+
from edsl.config import Config, CONFIG
|
9
|
+
from edsl.agents.Agent import Agent
|
10
|
+
from edsl.agents.AgentList import AgentList
|
11
|
+
from edsl.questions import QuestionBase
|
12
|
+
from edsl.questions import QuestionMultipleChoice
|
13
|
+
from edsl.questions import QuestionBudget
|
14
|
+
from edsl.questions import QuestionCheckBox
|
15
|
+
from edsl.questions import QuestionExtract
|
16
|
+
from edsl.questions import QuestionFreeText
|
17
|
+
from edsl.questions import QuestionFunctional
|
18
|
+
from edsl.questions import QuestionLikertFive
|
19
|
+
from edsl.questions import QuestionList
|
20
|
+
from edsl.questions import QuestionLinearScale
|
21
|
+
from edsl.questions import QuestionNumerical
|
22
|
+
from edsl.questions import QuestionRank
|
23
|
+
from edsl.questions import QuestionTopK
|
24
|
+
from edsl.questions import QuestionYesNo
|
25
|
+
from edsl.questions.question_registry import Question
|
26
|
+
from edsl.scenarios import Scenario
|
27
|
+
from edsl.scenarios import ScenarioList
|
28
|
+
|
29
|
+
# from edsl.utilities.interface import print_dict_with_rich
|
30
|
+
from edsl.surveys.Survey import Survey
|
31
|
+
from edsl.language_models.registry import Model
|
32
|
+
from edsl.language_models.ModelList import ModelList
|
33
|
+
from edsl.results.Results import Results
|
34
|
+
from edsl.data.Cache import Cache
|
35
|
+
from edsl.data.CacheEntry import CacheEntry
|
36
|
+
from edsl.data.CacheHandler import set_session_cache, unset_session_cache
|
37
|
+
from edsl.shared import shared_globals
|
38
|
+
from edsl.jobs.Jobs import Jobs
|
39
|
+
from edsl.notebooks.Notebook import Notebook
|
40
|
+
from edsl.study.Study import Study
|
41
|
+
from edsl.conjure.Conjure import Conjure
|
42
|
+
from edsl.coop.coop import Coop
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.1.29"
|
@@ -5,27 +5,14 @@ import copy
|
|
5
5
|
import inspect
|
6
6
|
import types
|
7
7
|
from typing import Any, Callable, Optional, Union, Dict, Sequence
|
8
|
-
|
9
|
-
from rich.table import Table
|
10
|
-
|
11
8
|
from edsl.Base import Base
|
12
|
-
|
13
|
-
from edsl.language_models import LanguageModel
|
14
|
-
from edsl.surveys.MemoryPlan import MemoryPlan
|
9
|
+
|
15
10
|
from edsl.exceptions.agents import (
|
16
11
|
AgentCombinationError,
|
17
12
|
AgentDirectAnswerFunctionError,
|
18
13
|
AgentDynamicTraitsFunctionError,
|
19
14
|
)
|
20
|
-
|
21
|
-
InvigilatorDebug,
|
22
|
-
InvigilatorHuman,
|
23
|
-
InvigilatorFunctional,
|
24
|
-
InvigilatorAI,
|
25
|
-
InvigilatorBase,
|
26
|
-
)
|
27
|
-
from edsl.language_models.registry import Model
|
28
|
-
from edsl.scenarios import Scenario
|
15
|
+
|
29
16
|
from edsl.agents.descriptors import (
|
30
17
|
TraitsDescriptor,
|
31
18
|
CodebookDescriptor,
|
@@ -38,10 +25,6 @@ from edsl.utilities.decorators import (
|
|
38
25
|
remove_edsl_version,
|
39
26
|
)
|
40
27
|
from edsl.data_transfer_models import AgentResponseDict
|
41
|
-
from edsl.prompts.library.agent_persona import AgentPersona
|
42
|
-
from edsl.data.Cache import Cache
|
43
|
-
|
44
|
-
|
45
28
|
from edsl.utilities.restricted_python import create_restricted_function
|
46
29
|
|
47
30
|
|
@@ -56,6 +39,7 @@ class Agent(Base):
|
|
56
39
|
name = NameDescriptor()
|
57
40
|
dynamic_traits_function_name = ""
|
58
41
|
answer_question_directly_function_name = ""
|
42
|
+
has_dynamic_traits_function = False
|
59
43
|
|
60
44
|
def __init__(
|
61
45
|
self,
|
@@ -129,12 +113,16 @@ class Agent(Base):
|
|
129
113
|
|
130
114
|
if self.dynamic_traits_function:
|
131
115
|
self.dynamic_traits_function_name = self.dynamic_traits_function.__name__
|
116
|
+
self.has_dynamic_traits_function = True
|
117
|
+
else:
|
118
|
+
self.has_dynamic_traits_function = False
|
132
119
|
|
133
120
|
if dynamic_traits_function_source_code:
|
134
121
|
self.dynamic_traits_function_name = dynamic_traits_function_name
|
135
122
|
self.dynamic_traits_function = create_restricted_function(
|
136
123
|
dynamic_traits_function_name, dynamic_traits_function
|
137
124
|
)
|
125
|
+
|
138
126
|
if answer_question_directly_source_code:
|
139
127
|
self.answer_question_directly_function_name = (
|
140
128
|
answer_question_directly_function_name
|
@@ -151,6 +139,8 @@ class Agent(Base):
|
|
151
139
|
self.current_question = None
|
152
140
|
|
153
141
|
if traits_presentation_template is not None:
|
142
|
+
from edsl.prompts.library.agent_persona import AgentPersona
|
143
|
+
|
154
144
|
self.traits_presentation_template = traits_presentation_template
|
155
145
|
self.agent_persona = AgentPersona(text=self.traits_presentation_template)
|
156
146
|
|
@@ -159,7 +149,7 @@ class Agent(Base):
|
|
159
149
|
|
160
150
|
This checks whether the dynamic traits function is valid.
|
161
151
|
"""
|
162
|
-
if self.
|
152
|
+
if self.has_dynamic_traits_function:
|
163
153
|
sig = inspect.signature(self.dynamic_traits_function)
|
164
154
|
if "question" in sig.parameters:
|
165
155
|
if len(sig.parameters) > 1:
|
@@ -189,7 +179,7 @@ class Agent(Base):
|
|
189
179
|
{'age': 10, 'hair': 'brown', 'height': 5.5}
|
190
180
|
|
191
181
|
"""
|
192
|
-
if self.
|
182
|
+
if self.has_dynamic_traits_function:
|
193
183
|
sig = inspect.signature(self.dynamic_traits_function)
|
194
184
|
if "question" in sig.parameters:
|
195
185
|
return self.dynamic_traits_function(question=self.current_question)
|
@@ -271,8 +261,9 @@ class Agent(Base):
|
|
271
261
|
def create_invigilator(
|
272
262
|
self,
|
273
263
|
*,
|
274
|
-
question: QuestionBase,
|
275
|
-
cache,
|
264
|
+
question: "QuestionBase",
|
265
|
+
cache: "Cache",
|
266
|
+
survey: Optional["Survey"] = None,
|
276
267
|
scenario: Optional[Scenario] = None,
|
277
268
|
model: Optional[LanguageModel] = None,
|
278
269
|
debug: bool = False,
|
@@ -280,7 +271,7 @@ class Agent(Base):
|
|
280
271
|
current_answers: Optional[dict] = None,
|
281
272
|
iteration: int = 1,
|
282
273
|
sidecar_model=None,
|
283
|
-
) -> InvigilatorBase:
|
274
|
+
) -> "InvigilatorBase":
|
284
275
|
"""Create an Invigilator.
|
285
276
|
|
286
277
|
An invigilator is an object that is responsible for administering a question to an agent.
|
@@ -294,6 +285,8 @@ class Agent(Base):
|
|
294
285
|
An invigator is an object that is responsible for administering a question to an agent and
|
295
286
|
recording the responses.
|
296
287
|
"""
|
288
|
+
from edsl import Model, Scenario
|
289
|
+
|
297
290
|
cache = cache
|
298
291
|
self.current_question = question
|
299
292
|
model = model or Model()
|
@@ -301,6 +294,7 @@ class Agent(Base):
|
|
301
294
|
invigilator = self._create_invigilator(
|
302
295
|
question=question,
|
303
296
|
scenario=scenario,
|
297
|
+
survey=survey,
|
304
298
|
model=model,
|
305
299
|
debug=debug,
|
306
300
|
memory_plan=memory_plan,
|
@@ -314,12 +308,13 @@ class Agent(Base):
|
|
314
308
|
async def async_answer_question(
|
315
309
|
self,
|
316
310
|
*,
|
317
|
-
question: QuestionBase,
|
318
|
-
cache: Cache,
|
319
|
-
scenario: Optional[Scenario] = None,
|
320
|
-
|
311
|
+
question: "QuestionBase",
|
312
|
+
cache: "Cache",
|
313
|
+
scenario: Optional["Scenario"] = None,
|
314
|
+
survey: Optional["Survey"] = None,
|
315
|
+
model: Optional["LanguageModel"] = None,
|
321
316
|
debug: bool = False,
|
322
|
-
memory_plan: Optional[MemoryPlan] = None,
|
317
|
+
memory_plan: Optional["MemoryPlan"] = None,
|
323
318
|
current_answers: Optional[dict] = None,
|
324
319
|
iteration: int = 0,
|
325
320
|
) -> AgentResponseDict:
|
@@ -349,6 +344,7 @@ class Agent(Base):
|
|
349
344
|
question=question,
|
350
345
|
cache=cache,
|
351
346
|
scenario=scenario,
|
347
|
+
survey=survey,
|
352
348
|
model=model,
|
353
349
|
debug=debug,
|
354
350
|
memory_plan=memory_plan,
|
@@ -362,21 +358,35 @@ class Agent(Base):
|
|
362
358
|
|
363
359
|
def _create_invigilator(
|
364
360
|
self,
|
365
|
-
question: QuestionBase,
|
366
|
-
cache: Optional[Cache] = None,
|
367
|
-
scenario: Optional[Scenario] = None,
|
368
|
-
model: Optional[LanguageModel] = None,
|
361
|
+
question: "QuestionBase",
|
362
|
+
cache: Optional["Cache"] = None,
|
363
|
+
scenario: Optional["Scenario"] = None,
|
364
|
+
model: Optional["LanguageModel"] = None,
|
365
|
+
survey: Optional["Survey"] = None,
|
369
366
|
debug: bool = False,
|
370
|
-
memory_plan: Optional[MemoryPlan] = None,
|
367
|
+
memory_plan: Optional["MemoryPlan"] = None,
|
371
368
|
current_answers: Optional[dict] = None,
|
372
369
|
iteration: int = 0,
|
373
370
|
sidecar_model=None,
|
374
|
-
) -> InvigilatorBase:
|
371
|
+
) -> "InvigilatorBase":
|
375
372
|
"""Create an Invigilator."""
|
373
|
+
from edsl import Model
|
374
|
+
from edsl import Scenario
|
375
|
+
|
376
376
|
model = model or Model()
|
377
377
|
scenario = scenario or Scenario()
|
378
378
|
|
379
|
+
from edsl.agents.Invigilator import (
|
380
|
+
InvigilatorDebug,
|
381
|
+
InvigilatorHuman,
|
382
|
+
InvigilatorFunctional,
|
383
|
+
InvigilatorAI,
|
384
|
+
InvigilatorBase,
|
385
|
+
)
|
386
|
+
|
379
387
|
if cache is None:
|
388
|
+
from edsl.data.Cache import Cache
|
389
|
+
|
380
390
|
cache = Cache()
|
381
391
|
|
382
392
|
if debug:
|
@@ -404,6 +414,7 @@ class Agent(Base):
|
|
404
414
|
self,
|
405
415
|
question=question,
|
406
416
|
scenario=scenario,
|
417
|
+
survey=survey,
|
407
418
|
model=model,
|
408
419
|
memory_plan=memory_plan,
|
409
420
|
current_answers=current_answers,
|
@@ -479,6 +490,29 @@ class Agent(Base):
|
|
479
490
|
"""
|
480
491
|
return self.data == other.data
|
481
492
|
|
493
|
+
def __getattr__(self, name):
|
494
|
+
# This will be called only if 'name' is not found in the usual places
|
495
|
+
# breakpoint()
|
496
|
+
if name == "has_dynamic_traits_function":
|
497
|
+
return self.has_dynamic_traits_function
|
498
|
+
|
499
|
+
if name in self.traits:
|
500
|
+
return self.traits[name]
|
501
|
+
raise AttributeError(
|
502
|
+
f"'{type(self).__name__}' object has no attribute '{name}'"
|
503
|
+
)
|
504
|
+
|
505
|
+
def __getstate__(self):
|
506
|
+
state = self.__dict__.copy()
|
507
|
+
# Include any additional state that needs to be serialized
|
508
|
+
return state
|
509
|
+
|
510
|
+
def __setstate__(self, state):
|
511
|
+
self.__dict__.update(state)
|
512
|
+
# Ensure _traits is initialized if it's missing
|
513
|
+
if "_traits" not in self.__dict__:
|
514
|
+
self._traits = {}
|
515
|
+
|
482
516
|
def print(self) -> None:
|
483
517
|
from rich import print_json
|
484
518
|
import json
|
@@ -535,9 +569,9 @@ class Agent(Base):
|
|
535
569
|
if dynamic_traits_func:
|
536
570
|
func = inspect.getsource(dynamic_traits_func)
|
537
571
|
raw_data["dynamic_traits_function_source_code"] = func
|
538
|
-
raw_data[
|
539
|
-
|
540
|
-
|
572
|
+
raw_data["dynamic_traits_function_name"] = (
|
573
|
+
self.dynamic_traits_function_name
|
574
|
+
)
|
541
575
|
if hasattr(self, "answer_question_directly"):
|
542
576
|
raw_data.pop(
|
543
577
|
"answer_question_directly", None
|
@@ -553,9 +587,9 @@ class Agent(Base):
|
|
553
587
|
raw_data["answer_question_directly_source_code"] = inspect.getsource(
|
554
588
|
answer_question_directly_func
|
555
589
|
)
|
556
|
-
raw_data[
|
557
|
-
|
558
|
-
|
590
|
+
raw_data["answer_question_directly_function_name"] = (
|
591
|
+
self.answer_question_directly_function_name
|
592
|
+
)
|
559
593
|
|
560
594
|
return raw_data
|
561
595
|
|
@@ -640,6 +674,8 @@ class Agent(Base):
|
|
640
674
|
>>> a.rich_print()
|
641
675
|
<rich.table.Table object at ...>
|
642
676
|
"""
|
677
|
+
from rich.table import Table
|
678
|
+
|
643
679
|
table_data, column_names = self._table()
|
644
680
|
table = Table(title=f"{self.__class__.__name__} Attributes")
|
645
681
|
for column in column_names:
|