edsl 0.1.29.dev3__tar.gz → 0.1.30__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.29.dev3 → edsl-0.1.30}/PKG-INFO +11 -10
- {edsl-0.1.29.dev3 → edsl-0.1.30}/README.md +10 -10
- edsl-0.1.30/edsl/Base.py +288 -0
- edsl-0.1.30/edsl/__init__.py +42 -0
- edsl-0.1.30/edsl/__version__.py +1 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/agents/Agent.py +79 -41
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/agents/AgentList.py +26 -26
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/agents/Invigilator.py +19 -2
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/agents/InvigilatorBase.py +15 -10
- edsl-0.1.30/edsl/agents/PromptConstructionMixin.py +376 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/agents/descriptors.py +2 -1
- {edsl-0.1.29.dev3/edsl → edsl-0.1.30/edsl/base}/Base.py +2 -1
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/config.py +2 -1
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/InputData.py +39 -8
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conversation/car_buying.py +1 -1
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/coop/coop.py +187 -150
- edsl-0.1.30/edsl/coop/utils.py +123 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/data/Cache.py +41 -18
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/data/CacheEntry.py +6 -7
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/data/SQLiteDict.py +11 -3
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/data_transfer_models.py +4 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/Answers.py +15 -1
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/Jobs.py +108 -49
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/buckets/ModelBuckets.py +14 -2
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/buckets/TokenBucket.py +32 -5
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/Interview.py +99 -79
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/InterviewTaskBuildingMixin.py +19 -24
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/runners/JobsRunnerAsyncio.py +16 -16
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/tasks/QuestionTaskCreator.py +10 -6
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/tasks/TaskHistory.py +4 -3
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/language_models/LanguageModel.py +17 -17
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/language_models/ModelList.py +1 -1
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/language_models/repair.py +8 -7
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/notebooks/Notebook.py +47 -10
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/Prompt.py +31 -19
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionBase.py +38 -13
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionBudget.py +5 -6
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionCheckBox.py +7 -3
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionExtract.py +5 -3
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionFreeText.py +7 -5
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionFunctional.py +34 -5
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionList.py +3 -4
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionMultipleChoice.py +68 -12
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionNumerical.py +4 -3
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/QuestionRank.py +5 -3
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/__init__.py +4 -3
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/descriptors.py +46 -4
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/question_registry.py +20 -31
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/settings.py +1 -1
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/results/Dataset.py +31 -0
- edsl-0.1.29.dev3/edsl/results/ResultsExportMixin.py → edsl-0.1.30/edsl/results/DatasetExportMixin.py +103 -91
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/results/Result.py +66 -70
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/results/Results.py +160 -68
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/results/ResultsDBMixin.py +7 -3
- edsl-0.1.30/edsl/results/ResultsExportMixin.py +43 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/results/ResultsGGMixin.py +3 -3
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/results/ResultsToolsMixin.py +5 -5
- edsl-0.1.30/edsl/scenarios/FileStore.py +299 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/scenarios/Scenario.py +16 -24
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/scenarios/ScenarioList.py +42 -17
- edsl-0.1.30/edsl/scenarios/ScenarioListExportMixin.py +32 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/scenarios/ScenarioListPdfMixin.py +2 -1
- edsl-0.1.30/edsl/scenarios/__init__.py +2 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/study/Study.py +8 -16
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/MemoryPlan.py +11 -4
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/Survey.py +88 -17
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/SurveyExportMixin.py +4 -2
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/SurveyFlowVisualizationMixin.py +6 -4
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/tools/plotting.py +4 -2
- edsl-0.1.30/edsl/utilities/__init__.py +22 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/interface.py +66 -45
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/utilities.py +11 -13
- {edsl-0.1.29.dev3 → edsl-0.1.30}/pyproject.toml +19 -21
- edsl-0.1.29.dev3/edsl/__init__.py +0 -42
- edsl-0.1.29.dev3/edsl/__version__.py +0 -1
- edsl-0.1.29.dev3/edsl/agents/PromptConstructionMixin.py +0 -134
- edsl-0.1.29.dev3/edsl/coop/utils.py +0 -155
- edsl-0.1.29.dev3/edsl/scenarios/__init__.py +0 -1
- edsl-0.1.29.dev3/edsl/utilities/__init__.py +0 -22
- {edsl-0.1.29.dev3 → edsl-0.1.30}/LICENSE +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/BaseDiff.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/agents/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/AgentConstructionMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/Conjure.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/InputDataCSV.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/InputDataMixinQuestionStats.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/InputDataPyRead.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/InputDataSPSS.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/InputDataStata.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/QuestionOptionMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/QuestionTypeMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/RawQuestion.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/SurveyResponses.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/examples/placeholder.txt +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/naming_utilities.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conjure/utilities.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conversation/Conversation.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conversation/mug_negotiation.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/conversation/next_speaker_utilities.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/coop/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/data/CacheHandler.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/data/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/data/orm.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/enums.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/agents.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/configuration.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/coop.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/data.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/general.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/jobs.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/language_models.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/prompts.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/questions.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/results.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/exceptions/surveys.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/AnthropicService.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/DeepInfraService.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/GoogleService.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/InferenceServiceABC.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/InferenceServicesCollection.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/OpenAIService.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/models_available_cache.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/rate_limits_cache.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/registry.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/inference_services/write_available.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/buckets/BucketCollection.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/InterviewStatistic.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/InterviewStatisticsCollection.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/InterviewStatusDictionary.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/InterviewStatusLog.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/InterviewStatusMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/ReportErrors.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/interview_exception_tracking.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/interview_status_enum.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/interviews/retry_management.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/runners/JobsRunnerStatusData.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/runners/JobsRunnerStatusMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/tasks/TaskCreators.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/tasks/TaskStatusLog.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/tasks/task_management.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/tasks/task_status_enum.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/tokens/InterviewTokenUsage.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/jobs/tokens/TokenUsage.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/language_models/RegisterLanguageModelsMeta.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/language_models/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/language_models/registry.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/language_models/unused/ReplicateBase.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/notebooks/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/QuestionInstructionsBase.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/agent_instructions.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/agent_persona.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/question_budget.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/question_checkbox.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/question_extract.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/question_freetext.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/question_linear_scale.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/question_list.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/question_multiple_choice.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/question_numerical.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/library/question_rank.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/prompt_config.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/prompts/registry.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/AnswerValidatorMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/RegisterQuestionsMeta.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/SimpleAskMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/compose_questions.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/derived/QuestionLikertFive.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/derived/QuestionLinearScale.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/derived/QuestionTopK.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/derived/QuestionYesNo.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/questions/derived/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/results/ResultsFetchMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/results/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/scenarios/ScenarioHtmlMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/scenarios/ScenarioImageMixin.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/shared.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/study/ObjectEntry.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/study/ProofOfWork.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/study/SnapShot.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/study/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/DAG.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/Memory.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/Rule.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/RuleCollection.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/SurveyCSS.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/base.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/surveys/descriptors.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/tools/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/tools/clusters.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/tools/embeddings.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/tools/embeddings_plotting.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/tools/summarize.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/SystemInfo.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/ast_utilities.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/data/Registry.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/data/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/data/scooter_results.json +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/decorators.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/gcp_bucket/__init__.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/gcp_bucket/cloud_storage.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/gcp_bucket/simple_example.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/edsl/utilities/repair_functions.py +0 -0
- {edsl-0.1.29.dev3 → edsl-0.1.30}/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.30
|
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.30/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.30"
|
@@ -4,28 +4,16 @@ from __future__ import annotations
|
|
4
4
|
import copy
|
5
5
|
import inspect
|
6
6
|
import types
|
7
|
-
from typing import
|
8
|
-
|
9
|
-
from rich.table import Table
|
10
|
-
|
7
|
+
from typing import Callable, Optional, Union
|
8
|
+
from uuid import uuid4
|
11
9
|
from edsl.Base import Base
|
12
|
-
|
13
|
-
from edsl.language_models import LanguageModel
|
14
|
-
from edsl.surveys.MemoryPlan import MemoryPlan
|
10
|
+
|
15
11
|
from edsl.exceptions.agents import (
|
16
12
|
AgentCombinationError,
|
17
13
|
AgentDirectAnswerFunctionError,
|
18
14
|
AgentDynamicTraitsFunctionError,
|
19
15
|
)
|
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
|
16
|
+
|
29
17
|
from edsl.agents.descriptors import (
|
30
18
|
TraitsDescriptor,
|
31
19
|
CodebookDescriptor,
|
@@ -38,10 +26,6 @@ from edsl.utilities.decorators import (
|
|
38
26
|
remove_edsl_version,
|
39
27
|
)
|
40
28
|
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
29
|
from edsl.utilities.restricted_python import create_restricted_function
|
46
30
|
|
47
31
|
|
@@ -56,6 +40,7 @@ class Agent(Base):
|
|
56
40
|
name = NameDescriptor()
|
57
41
|
dynamic_traits_function_name = ""
|
58
42
|
answer_question_directly_function_name = ""
|
43
|
+
has_dynamic_traits_function = False
|
59
44
|
|
60
45
|
def __init__(
|
61
46
|
self,
|
@@ -129,12 +114,16 @@ class Agent(Base):
|
|
129
114
|
|
130
115
|
if self.dynamic_traits_function:
|
131
116
|
self.dynamic_traits_function_name = self.dynamic_traits_function.__name__
|
117
|
+
self.has_dynamic_traits_function = True
|
118
|
+
else:
|
119
|
+
self.has_dynamic_traits_function = False
|
132
120
|
|
133
121
|
if dynamic_traits_function_source_code:
|
134
122
|
self.dynamic_traits_function_name = dynamic_traits_function_name
|
135
123
|
self.dynamic_traits_function = create_restricted_function(
|
136
124
|
dynamic_traits_function_name, dynamic_traits_function
|
137
125
|
)
|
126
|
+
|
138
127
|
if answer_question_directly_source_code:
|
139
128
|
self.answer_question_directly_function_name = (
|
140
129
|
answer_question_directly_function_name
|
@@ -151,6 +140,8 @@ class Agent(Base):
|
|
151
140
|
self.current_question = None
|
152
141
|
|
153
142
|
if traits_presentation_template is not None:
|
143
|
+
from edsl.prompts.library.agent_persona import AgentPersona
|
144
|
+
|
154
145
|
self.traits_presentation_template = traits_presentation_template
|
155
146
|
self.agent_persona = AgentPersona(text=self.traits_presentation_template)
|
156
147
|
|
@@ -159,7 +150,7 @@ class Agent(Base):
|
|
159
150
|
|
160
151
|
This checks whether the dynamic traits function is valid.
|
161
152
|
"""
|
162
|
-
if self.
|
153
|
+
if self.has_dynamic_traits_function:
|
163
154
|
sig = inspect.signature(self.dynamic_traits_function)
|
164
155
|
if "question" in sig.parameters:
|
165
156
|
if len(sig.parameters) > 1:
|
@@ -189,7 +180,7 @@ class Agent(Base):
|
|
189
180
|
{'age': 10, 'hair': 'brown', 'height': 5.5}
|
190
181
|
|
191
182
|
"""
|
192
|
-
if self.
|
183
|
+
if self.has_dynamic_traits_function:
|
193
184
|
sig = inspect.signature(self.dynamic_traits_function)
|
194
185
|
if "question" in sig.parameters:
|
195
186
|
return self.dynamic_traits_function(question=self.current_question)
|
@@ -271,8 +262,9 @@ class Agent(Base):
|
|
271
262
|
def create_invigilator(
|
272
263
|
self,
|
273
264
|
*,
|
274
|
-
question: QuestionBase,
|
275
|
-
cache,
|
265
|
+
question: "QuestionBase",
|
266
|
+
cache: "Cache",
|
267
|
+
survey: Optional["Survey"] = None,
|
276
268
|
scenario: Optional[Scenario] = None,
|
277
269
|
model: Optional[LanguageModel] = None,
|
278
270
|
debug: bool = False,
|
@@ -280,7 +272,7 @@ class Agent(Base):
|
|
280
272
|
current_answers: Optional[dict] = None,
|
281
273
|
iteration: int = 1,
|
282
274
|
sidecar_model=None,
|
283
|
-
) -> InvigilatorBase:
|
275
|
+
) -> "InvigilatorBase":
|
284
276
|
"""Create an Invigilator.
|
285
277
|
|
286
278
|
An invigilator is an object that is responsible for administering a question to an agent.
|
@@ -294,6 +286,8 @@ class Agent(Base):
|
|
294
286
|
An invigator is an object that is responsible for administering a question to an agent and
|
295
287
|
recording the responses.
|
296
288
|
"""
|
289
|
+
from edsl import Model, Scenario
|
290
|
+
|
297
291
|
cache = cache
|
298
292
|
self.current_question = question
|
299
293
|
model = model or Model()
|
@@ -301,6 +295,7 @@ class Agent(Base):
|
|
301
295
|
invigilator = self._create_invigilator(
|
302
296
|
question=question,
|
303
297
|
scenario=scenario,
|
298
|
+
survey=survey,
|
304
299
|
model=model,
|
305
300
|
debug=debug,
|
306
301
|
memory_plan=memory_plan,
|
@@ -314,12 +309,13 @@ class Agent(Base):
|
|
314
309
|
async def async_answer_question(
|
315
310
|
self,
|
316
311
|
*,
|
317
|
-
question: QuestionBase,
|
318
|
-
cache: Cache,
|
319
|
-
scenario: Optional[Scenario] = None,
|
320
|
-
|
312
|
+
question: "QuestionBase",
|
313
|
+
cache: "Cache",
|
314
|
+
scenario: Optional["Scenario"] = None,
|
315
|
+
survey: Optional["Survey"] = None,
|
316
|
+
model: Optional["LanguageModel"] = None,
|
321
317
|
debug: bool = False,
|
322
|
-
memory_plan: Optional[MemoryPlan] = None,
|
318
|
+
memory_plan: Optional["MemoryPlan"] = None,
|
323
319
|
current_answers: Optional[dict] = None,
|
324
320
|
iteration: int = 0,
|
325
321
|
) -> AgentResponseDict:
|
@@ -349,6 +345,7 @@ class Agent(Base):
|
|
349
345
|
question=question,
|
350
346
|
cache=cache,
|
351
347
|
scenario=scenario,
|
348
|
+
survey=survey,
|
352
349
|
model=model,
|
353
350
|
debug=debug,
|
354
351
|
memory_plan=memory_plan,
|
@@ -362,21 +359,35 @@ class Agent(Base):
|
|
362
359
|
|
363
360
|
def _create_invigilator(
|
364
361
|
self,
|
365
|
-
question: QuestionBase,
|
366
|
-
cache: Optional[Cache] = None,
|
367
|
-
scenario: Optional[Scenario] = None,
|
368
|
-
model: Optional[LanguageModel] = None,
|
362
|
+
question: "QuestionBase",
|
363
|
+
cache: Optional["Cache"] = None,
|
364
|
+
scenario: Optional["Scenario"] = None,
|
365
|
+
model: Optional["LanguageModel"] = None,
|
366
|
+
survey: Optional["Survey"] = None,
|
369
367
|
debug: bool = False,
|
370
|
-
memory_plan: Optional[MemoryPlan] = None,
|
368
|
+
memory_plan: Optional["MemoryPlan"] = None,
|
371
369
|
current_answers: Optional[dict] = None,
|
372
370
|
iteration: int = 0,
|
373
371
|
sidecar_model=None,
|
374
|
-
) -> InvigilatorBase:
|
372
|
+
) -> "InvigilatorBase":
|
375
373
|
"""Create an Invigilator."""
|
374
|
+
from edsl import Model
|
375
|
+
from edsl import Scenario
|
376
|
+
|
376
377
|
model = model or Model()
|
377
378
|
scenario = scenario or Scenario()
|
378
379
|
|
380
|
+
from edsl.agents.Invigilator import (
|
381
|
+
InvigilatorDebug,
|
382
|
+
InvigilatorHuman,
|
383
|
+
InvigilatorFunctional,
|
384
|
+
InvigilatorAI,
|
385
|
+
InvigilatorBase,
|
386
|
+
)
|
387
|
+
|
379
388
|
if cache is None:
|
389
|
+
from edsl.data.Cache import Cache
|
390
|
+
|
380
391
|
cache = Cache()
|
381
392
|
|
382
393
|
if debug:
|
@@ -404,6 +415,7 @@ class Agent(Base):
|
|
404
415
|
self,
|
405
416
|
question=question,
|
406
417
|
scenario=scenario,
|
418
|
+
survey=survey,
|
407
419
|
model=model,
|
408
420
|
memory_plan=memory_plan,
|
409
421
|
current_answers=current_answers,
|
@@ -479,6 +491,29 @@ class Agent(Base):
|
|
479
491
|
"""
|
480
492
|
return self.data == other.data
|
481
493
|
|
494
|
+
def __getattr__(self, name):
|
495
|
+
# This will be called only if 'name' is not found in the usual places
|
496
|
+
# breakpoint()
|
497
|
+
if name == "has_dynamic_traits_function":
|
498
|
+
return self.has_dynamic_traits_function
|
499
|
+
|
500
|
+
if name in self.traits:
|
501
|
+
return self.traits[name]
|
502
|
+
raise AttributeError(
|
503
|
+
f"'{type(self).__name__}' object has no attribute '{name}'"
|
504
|
+
)
|
505
|
+
|
506
|
+
def __getstate__(self):
|
507
|
+
state = self.__dict__.copy()
|
508
|
+
# Include any additional state that needs to be serialized
|
509
|
+
return state
|
510
|
+
|
511
|
+
def __setstate__(self, state):
|
512
|
+
self.__dict__.update(state)
|
513
|
+
# Ensure _traits is initialized if it's missing
|
514
|
+
if "_traits" not in self.__dict__:
|
515
|
+
self._traits = {}
|
516
|
+
|
482
517
|
def print(self) -> None:
|
483
518
|
from rich import print_json
|
484
519
|
import json
|
@@ -640,6 +675,8 @@ class Agent(Base):
|
|
640
675
|
>>> a.rich_print()
|
641
676
|
<rich.table.Table object at ...>
|
642
677
|
"""
|
678
|
+
from rich.table import Table
|
679
|
+
|
643
680
|
table_data, column_names = self._table()
|
644
681
|
table = Table(title=f"{self.__class__.__name__} Attributes")
|
645
682
|
for column in column_names:
|
@@ -652,13 +689,14 @@ class Agent(Base):
|
|
652
689
|
return table
|
653
690
|
|
654
691
|
@classmethod
|
655
|
-
def example(cls) -> Agent:
|
656
|
-
"""
|
692
|
+
def example(cls, randomize: bool = False) -> Agent:
|
693
|
+
"""
|
694
|
+
Returns an example Agent instance.
|
657
695
|
|
658
|
-
|
659
|
-
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.
|
660
697
|
"""
|
661
|
-
|
698
|
+
addition = "" if not randomize else str(uuid4())
|
699
|
+
return cls(traits={"age": 22, "hair": f"brown{addition}", "height": 5.5})
|
662
700
|
|
663
701
|
def code(self) -> str:
|
664
702
|
"""Return the code for the agent.
|