edsl 0.1.35__tar.gz → 0.1.36.dev1__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.35 → edsl-0.1.36.dev1}/PKG-INFO +1 -1
- edsl-0.1.36.dev1/edsl/__version__.py +1 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/agents/Agent.py +38 -14
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/agents/Invigilator.py +2 -1
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/agents/PromptConstructor.py +6 -51
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/Jobs.py +146 -48
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/interviews/Interview.py +42 -15
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/interviews/InterviewExceptionEntry.py +0 -3
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/tasks/QuestionTaskCreator.py +1 -5
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/LanguageModel.py +3 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/prompts/Prompt.py +24 -38
- edsl-0.1.36.dev1/edsl/prompts/__init__.py +2 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionBasePromptsMixin.py +18 -18
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/descriptors.py +24 -24
- edsl-0.1.36.dev1/edsl/questions/templates/budget/__pycache__/__init__.cpython-311.pyc +0 -0
- edsl-0.1.36.dev1/edsl/questions/templates/extract/__pycache__/__init__.cpython-311.pyc +0 -0
- edsl-0.1.36.dev1/edsl/questions/templates/likert_five/__pycache__/__init__.cpython-311.pyc +0 -0
- edsl-0.1.36.dev1/edsl/questions/templates/rank/__pycache__/__init__.cpython-311.pyc +0 -0
- edsl-0.1.36.dev1/edsl/questions/templates/top_k/__pycache__/__init__.cpython-311.pyc +0 -0
- edsl-0.1.36.dev1/edsl/questions/templates/yes_no/__pycache__/__init__.cpython-311.pyc +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/pyproject.toml +1 -1
- edsl-0.1.35/edsl/__version__.py +0 -1
- edsl-0.1.35/edsl/jobs/FailedQuestion.py +0 -78
- edsl-0.1.35/edsl/jobs/interviews/InterviewStatusMixin.py +0 -33
- edsl-0.1.35/edsl/jobs/tasks/task_management.py +0 -13
- edsl-0.1.35/edsl/prompts/QuestionInstructionsBase.py +0 -10
- edsl-0.1.35/edsl/prompts/__init__.py +0 -2
- edsl-0.1.35/edsl/prompts/library/agent_instructions.py +0 -38
- edsl-0.1.35/edsl/prompts/library/agent_persona.py +0 -21
- edsl-0.1.35/edsl/prompts/library/question_budget.py +0 -30
- edsl-0.1.35/edsl/prompts/library/question_checkbox.py +0 -38
- edsl-0.1.35/edsl/prompts/library/question_extract.py +0 -23
- edsl-0.1.35/edsl/prompts/library/question_freetext.py +0 -18
- edsl-0.1.35/edsl/prompts/library/question_linear_scale.py +0 -24
- edsl-0.1.35/edsl/prompts/library/question_list.py +0 -26
- edsl-0.1.35/edsl/prompts/library/question_multiple_choice.py +0 -54
- edsl-0.1.35/edsl/prompts/library/question_numerical.py +0 -35
- edsl-0.1.35/edsl/prompts/library/question_rank.py +0 -25
- edsl-0.1.35/edsl/prompts/prompt_config.py +0 -37
- edsl-0.1.35/edsl/prompts/registry.py +0 -202
- {edsl-0.1.35 → edsl-0.1.36.dev1}/LICENSE +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/README.md +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/Base.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/BaseDiff.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/TemplateLoader.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/agents/AgentList.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/agents/InvigilatorBase.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/agents/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/agents/descriptors.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/agents/prompt_helpers.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/AutoStudy.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/StageBase.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/StageGenerateSurvey.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/StageLabelQuestions.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/StagePersona.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/StagePersonaDimensionValueRanges.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/StagePersonaDimensionValues.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/StagePersonaDimensions.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/StageQuestions.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/SurveyCreatorPipeline.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/auto/utilities.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/base/Base.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/config.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/AgentConstructionMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/Conjure.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/InputData.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/InputDataCSV.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/InputDataMixinQuestionStats.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/InputDataPyRead.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/InputDataSPSS.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/InputDataStata.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/QuestionOptionMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/QuestionTypeMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/RawQuestion.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/SurveyResponses.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/examples/placeholder.txt +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/naming_utilities.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conjure/utilities.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conversation/Conversation.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conversation/car_buying.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conversation/mug_negotiation.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/conversation/next_speaker_utilities.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/coop/PriceFetcher.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/coop/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/coop/coop.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/coop/utils.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/data/Cache.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/data/CacheEntry.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/data/CacheHandler.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/data/SQLiteDict.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/data/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/data/orm.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/data_transfer_models.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/enums.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/agents.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/configuration.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/coop.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/data.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/general.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/jobs.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/language_models.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/prompts.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/questions.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/results.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/exceptions/surveys.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/AnthropicService.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/AwsBedrock.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/AzureAI.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/DeepInfraService.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/GoogleService.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/GroqService.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/InferenceServiceABC.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/InferenceServicesCollection.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/MistralAIService.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/OllamaService.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/OpenAIService.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/TestService.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/TogetherAIService.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/models_available_cache.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/rate_limits_cache.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/registry.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/inference_services/write_available.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/Answers.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/buckets/BucketCollection.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/buckets/ModelBuckets.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/buckets/TokenBucket.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/interviews/InterviewExceptionCollection.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/interviews/InterviewStatistic.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/interviews/InterviewStatisticsCollection.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/interviews/InterviewStatusDictionary.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/interviews/InterviewStatusLog.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/interviews/ReportErrors.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/interviews/interview_status_enum.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/runners/JobsRunnerAsyncio.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/runners/JobsRunnerStatus.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/runners/JobsRunnerStatusData.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/tasks/TaskCreators.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/tasks/TaskHistory.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/tasks/TaskStatusLog.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/tasks/task_status_enum.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/tokens/InterviewTokenUsage.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/jobs/tokens/TokenUsage.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/ModelList.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/RegisterLanguageModelsMeta.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/fake_openai_call.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/fake_openai_service.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/registry.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/repair.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/unused/ReplicateBase.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/language_models/utilities.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/notebooks/Notebook.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/notebooks/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/AnswerValidatorMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionBase.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionBaseGenMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionBudget.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionCheckBox.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionExtract.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionFreeText.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionFunctional.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionList.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionMultipleChoice.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionNumerical.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/QuestionRank.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/Quick.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/RegisterQuestionsMeta.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/ResponseValidatorABC.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/SimpleAskMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/compose_questions.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/decorators.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/derived/QuestionLikertFive.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/derived/QuestionLinearScale.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/derived/QuestionTopK.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/derived/QuestionYesNo.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/derived/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/prompt_templates/question_budget.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/prompt_templates/question_checkbox.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/prompt_templates/question_extract.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/prompt_templates/question_free_text.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/prompt_templates/question_linear_scale.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/prompt_templates/question_list.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/prompt_templates/question_multiple_choice.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/prompt_templates/question_numerical.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/question_registry.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/settings.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/__pycache__/__init__.cpython-311.pyc +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/budget/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/budget/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/budget/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/checkbox/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/checkbox/__pycache__/__init__.cpython-311.pyc +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/checkbox/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/checkbox/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/extract/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/extract/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/extract/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/free_text/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/free_text/__pycache__/__init__.cpython-311.pyc +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/free_text/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/free_text/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/likert_five/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/likert_five/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/likert_five/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/linear_scale/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/linear_scale/__pycache__/__init__.cpython-311.pyc +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/linear_scale/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/linear_scale/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/list/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/list/__pycache__/__init__.cpython-311.pyc +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/list/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/list/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/multiple_choice/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/multiple_choice/__pycache__/__init__.cpython-311.pyc +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/multiple_choice/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/multiple_choice/html.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/multiple_choice/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/numerical/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/numerical/__pycache__/__init__.cpython-311.pyc +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/numerical/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/numerical/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/rank/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/rank/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/rank/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/top_k/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/top_k/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/top_k/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/yes_no/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/yes_no/answering_instructions.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/questions/templates/yes_no/question_presentation.jinja +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/Dataset.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/DatasetExportMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/DatasetTree.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/Result.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/Results.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/ResultsDBMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/ResultsExportMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/ResultsFetchMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/ResultsGGMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/ResultsToolsMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/Selector.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/results/tree_explore.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/scenarios/FileStore.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/scenarios/Scenario.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/scenarios/ScenarioHtmlMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/scenarios/ScenarioList.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/scenarios/ScenarioListExportMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/scenarios/ScenarioListPdfMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/scenarios/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/shared.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/study/ObjectEntry.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/study/ProofOfWork.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/study/SnapShot.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/study/Study.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/study/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/DAG.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/Memory.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/MemoryPlan.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/Rule.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/RuleCollection.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/Survey.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/SurveyCSS.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/SurveyExportMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/SurveyFlowVisualizationMixin.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/SurveyQualtricsImport.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/base.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/descriptors.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/instructions/ChangeInstruction.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/instructions/Instruction.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/instructions/InstructionCollection.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/surveys/instructions/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/base.html +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/exceptions_by_model.html +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/exceptions_by_question_name.html +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/exceptions_by_type.html +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/interview_details.html +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/interviews.html +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/overview.html +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/performance_plot.html +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/report.css +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/report.html +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/templates/error_reporting/report.js +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/tools/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/tools/clusters.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/tools/embeddings.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/tools/embeddings_plotting.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/tools/plotting.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/tools/summarize.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/SystemInfo.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/ast_utilities.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/data/Registry.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/data/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/data/scooter_results.json +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/decorators.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/gcp_bucket/__init__.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/gcp_bucket/cloud_storage.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/interface.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/repair_functions.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/restricted_python.py +0 -0
- {edsl-0.1.35 → edsl-0.1.36.dev1}/edsl/utilities/utilities.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.1.36.dev1"
|
@@ -8,6 +8,9 @@ from typing import Callable, Optional, Union, Any
|
|
8
8
|
from uuid import uuid4
|
9
9
|
from edsl.Base import Base
|
10
10
|
|
11
|
+
from edsl.prompts import Prompt
|
12
|
+
from edsl.exceptions import QuestionScenarioRenderError
|
13
|
+
|
11
14
|
from edsl.exceptions.agents import (
|
12
15
|
AgentCombinationError,
|
13
16
|
AgentDirectAnswerFunctionError,
|
@@ -44,7 +47,6 @@ class Agent(Base):
|
|
44
47
|
|
45
48
|
def __init__(
|
46
49
|
self,
|
47
|
-
# *,
|
48
50
|
traits: Optional[dict] = None,
|
49
51
|
name: Optional[str] = None,
|
50
52
|
codebook: Optional[dict] = None,
|
@@ -112,6 +114,7 @@ class Agent(Base):
|
|
112
114
|
self.instruction = instruction or self.default_instruction
|
113
115
|
self.dynamic_traits_function = dynamic_traits_function
|
114
116
|
|
117
|
+
# Deal with dynamic traits function
|
115
118
|
if self.dynamic_traits_function:
|
116
119
|
self.dynamic_traits_function_name = self.dynamic_traits_function.__name__
|
117
120
|
self.has_dynamic_traits_function = True
|
@@ -124,6 +127,7 @@ class Agent(Base):
|
|
124
127
|
dynamic_traits_function_name, dynamic_traits_function
|
125
128
|
)
|
126
129
|
|
130
|
+
# Deal with direct answer function
|
127
131
|
if answer_question_directly_source_code:
|
128
132
|
self.answer_question_directly_function_name = (
|
129
133
|
answer_question_directly_function_name
|
@@ -140,10 +144,34 @@ class Agent(Base):
|
|
140
144
|
self.current_question = None
|
141
145
|
|
142
146
|
if traits_presentation_template is not None:
|
143
|
-
from edsl.prompts.library.agent_persona import AgentPersona
|
144
|
-
|
145
147
|
self.traits_presentation_template = traits_presentation_template
|
146
|
-
|
148
|
+
else:
|
149
|
+
self.traits_presentation_template = """Your traits: {{ traits }}"""
|
150
|
+
|
151
|
+
@property
|
152
|
+
def agent_persona(self) -> Prompt:
|
153
|
+
return Prompt(text=self.traits_presentation_template)
|
154
|
+
|
155
|
+
def prompt(self) -> str:
|
156
|
+
"""Return the prompt for the agent.
|
157
|
+
|
158
|
+
Example usage:
|
159
|
+
|
160
|
+
>>> a = Agent(traits = {"age": 10, "hair": "brown", "height": 5.5})
|
161
|
+
>>> a.prompt()
|
162
|
+
Prompt(text=\"""Your traits: {'age': 10, 'hair': 'brown', 'height': 5.5}\""")
|
163
|
+
"""
|
164
|
+
replacement_dict = (
|
165
|
+
self.traits | {"traits": self.traits} | {"codebook": self.codebook}
|
166
|
+
)
|
167
|
+
if undefined := self.agent_persona.undefined_template_variables(
|
168
|
+
replacement_dict
|
169
|
+
):
|
170
|
+
raise QuestionScenarioRenderError(
|
171
|
+
f"Agent persona still has variables that were not rendered: {undefined}"
|
172
|
+
)
|
173
|
+
else:
|
174
|
+
return self.agent_persona.render(replacement_dict)
|
147
175
|
|
148
176
|
def _check_dynamic_traits_function(self) -> None:
|
149
177
|
"""Check whether dynamic trait function is valid.
|
@@ -252,7 +280,6 @@ class Agent(Base):
|
|
252
280
|
warnings.warn(
|
253
281
|
"Warning: overwriting existing answer_question_directly method"
|
254
282
|
)
|
255
|
-
# print("Warning: overwriting existing answer_question_directly method")
|
256
283
|
|
257
284
|
self.validate_response = validate_response
|
258
285
|
self.translate_response = translate_response
|
@@ -575,9 +602,6 @@ class Agent(Base):
|
|
575
602
|
if self.name == None:
|
576
603
|
raw_data.pop("name")
|
577
604
|
|
578
|
-
import inspect
|
579
|
-
|
580
|
-
# print(raw_data)
|
581
605
|
if hasattr(self, "dynamic_traits_function"):
|
582
606
|
raw_data.pop(
|
583
607
|
"dynamic_traits_function", None
|
@@ -586,9 +610,9 @@ class Agent(Base):
|
|
586
610
|
if dynamic_traits_func:
|
587
611
|
func = inspect.getsource(dynamic_traits_func)
|
588
612
|
raw_data["dynamic_traits_function_source_code"] = func
|
589
|
-
raw_data[
|
590
|
-
|
591
|
-
|
613
|
+
raw_data["dynamic_traits_function_name"] = (
|
614
|
+
self.dynamic_traits_function_name
|
615
|
+
)
|
592
616
|
if hasattr(self, "answer_question_directly"):
|
593
617
|
raw_data.pop(
|
594
618
|
"answer_question_directly", None
|
@@ -604,9 +628,9 @@ class Agent(Base):
|
|
604
628
|
raw_data["answer_question_directly_source_code"] = inspect.getsource(
|
605
629
|
answer_question_directly_func
|
606
630
|
)
|
607
|
-
raw_data[
|
608
|
-
|
609
|
-
|
631
|
+
raw_data["answer_question_directly_function_name"] = (
|
632
|
+
self.answer_question_directly_function_name
|
633
|
+
)
|
610
634
|
|
611
635
|
return raw_data
|
612
636
|
|
@@ -4,7 +4,8 @@ from typing import Dict, Any, Optional
|
|
4
4
|
|
5
5
|
from edsl.prompts.Prompt import Prompt
|
6
6
|
from edsl.utilities.decorators import sync_wrapper, jupyter_nb_handler
|
7
|
-
|
7
|
+
|
8
|
+
# from edsl.prompts.registry import get_classes as prompt_lookup
|
8
9
|
from edsl.exceptions.questions import QuestionAnswerValidationError
|
9
10
|
from edsl.agents.InvigilatorBase import InvigilatorBase
|
10
11
|
from edsl.data_transfer_models import AgentResponseDict, EDSLResultObjectInput
|
@@ -7,7 +7,8 @@ from jinja2 import Environment, meta
|
|
7
7
|
|
8
8
|
from edsl.prompts.Prompt import Prompt
|
9
9
|
from edsl.data_transfer_models import ImageInfo
|
10
|
-
|
10
|
+
|
11
|
+
# from edsl.prompts.registry import get_classes as prompt_lookup
|
11
12
|
from edsl.exceptions import QuestionScenarioRenderError
|
12
13
|
|
13
14
|
from edsl.agents.prompt_helpers import PromptComponent, PromptList, PromptPlan
|
@@ -75,17 +76,8 @@ class PromptConstructor:
|
|
75
76
|
|
76
77
|
if self.agent == Agent(): # if agent is empty, then return an empty prompt
|
77
78
|
return Prompt(text="")
|
78
|
-
|
79
|
-
|
80
|
-
component_type="agent_instructions",
|
81
|
-
model=self.model.model,
|
82
|
-
)
|
83
|
-
if len(applicable_prompts) == 0:
|
84
|
-
raise Exception("No applicable prompts found")
|
85
|
-
self._agent_instructions_prompt = applicable_prompts[0](
|
86
|
-
text=self.agent.instruction
|
87
|
-
)
|
88
|
-
return self._agent_instructions_prompt
|
79
|
+
|
80
|
+
return Prompt(text=self.agent.instruction)
|
89
81
|
|
90
82
|
@property
|
91
83
|
def agent_persona_prompt(self) -> Prompt:
|
@@ -93,51 +85,14 @@ class PromptConstructor:
|
|
93
85
|
>>> from edsl.agents.InvigilatorBase import InvigilatorBase
|
94
86
|
>>> i = InvigilatorBase.example()
|
95
87
|
>>> i.prompt_constructor.agent_persona_prompt
|
96
|
-
Prompt(text=\"""
|
97
|
-
{'age': 22, 'hair': 'brown', 'height': 5.5}\""")
|
98
|
-
|
88
|
+
Prompt(text=\"""Your traits: {'age': 22, 'hair': 'brown', 'height': 5.5}\""")
|
99
89
|
"""
|
100
90
|
from edsl import Agent
|
101
91
|
|
102
|
-
if hasattr(self, "_agent_persona_prompt"):
|
103
|
-
return self._agent_persona_prompt
|
104
|
-
|
105
92
|
if self.agent == Agent(): # if agent is empty, then return an empty prompt
|
106
93
|
return Prompt(text="")
|
107
94
|
|
108
|
-
|
109
|
-
applicable_prompts = prompt_lookup(
|
110
|
-
component_type="agent_persona",
|
111
|
-
model=self.model.model,
|
112
|
-
)
|
113
|
-
persona_prompt_template = applicable_prompts[0]()
|
114
|
-
else:
|
115
|
-
persona_prompt_template = self.agent.agent_persona
|
116
|
-
|
117
|
-
# TODO: This multiple passing of agent traits - not sure if it is necessary. Not harmful.
|
118
|
-
template_parameter_dictionary = (
|
119
|
-
self.agent.traits
|
120
|
-
| {"traits": self.agent.traits}
|
121
|
-
| {"codebook": self.agent.codebook}
|
122
|
-
| {"traits": self.agent.traits}
|
123
|
-
)
|
124
|
-
|
125
|
-
if undefined := persona_prompt_template.undefined_template_variables(
|
126
|
-
template_parameter_dictionary
|
127
|
-
):
|
128
|
-
raise QuestionScenarioRenderError(
|
129
|
-
f"Agent persona still has variables that were not rendered: {undefined}"
|
130
|
-
)
|
131
|
-
|
132
|
-
persona_prompt = persona_prompt_template.render(template_parameter_dictionary)
|
133
|
-
if persona_prompt.has_variables:
|
134
|
-
raise QuestionScenarioRenderError(
|
135
|
-
"Agent persona still has variables that were not rendered."
|
136
|
-
)
|
137
|
-
|
138
|
-
self._agent_persona_prompt = persona_prompt
|
139
|
-
|
140
|
-
return self._agent_persona_prompt
|
95
|
+
return self.agent.prompt()
|
141
96
|
|
142
97
|
def prior_answers_dict(self) -> dict:
|
143
98
|
d = self.survey.question_names_to_questions()
|
@@ -180,17 +180,15 @@ class Jobs(Base):
|
|
180
180
|
scenario_indices.append(scenario_index)
|
181
181
|
models.append(invigilator.model.model)
|
182
182
|
question_names.append(invigilator.question.question_name)
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
) + output_tokens / float(inverse_output_price)
|
193
|
-
costs.append(cost)
|
183
|
+
|
184
|
+
prompt_cost = self.estimate_prompt_cost(
|
185
|
+
system_prompt=system_prompt,
|
186
|
+
user_prompt=user_prompt,
|
187
|
+
price_lookup=price_lookup,
|
188
|
+
inference_service=invigilator.model._inference_service_,
|
189
|
+
model=invigilator.model.model,
|
190
|
+
)
|
191
|
+
costs.append(prompt_cost["cost"])
|
194
192
|
|
195
193
|
d = Dataset(
|
196
194
|
[
|
@@ -214,50 +212,150 @@ class Jobs(Base):
|
|
214
212
|
"""Print the prompts."""
|
215
213
|
self.prompts().to_scenario_list().print(format="rich")
|
216
214
|
|
217
|
-
|
218
|
-
|
215
|
+
@staticmethod
|
216
|
+
def estimate_prompt_cost(
|
217
|
+
system_prompt: str,
|
218
|
+
user_prompt: str,
|
219
|
+
price_lookup: dict,
|
220
|
+
inference_service: str,
|
221
|
+
model: str,
|
222
|
+
):
|
223
|
+
"""Estimates the cost of a prompt. Takes piping into account."""
|
219
224
|
|
220
|
-
|
221
|
-
|
225
|
+
def get_piping_multiplier(prompt: str):
|
226
|
+
"""Returns 2 if a prompt includes Jinja brances, and 1 otherwise."""
|
222
227
|
|
223
|
-
|
228
|
+
if "{{" in prompt and "}}" in prompt:
|
229
|
+
return 2
|
230
|
+
return 1
|
224
231
|
|
225
|
-
|
226
|
-
|
227
|
-
|
232
|
+
# Look up prices per token
|
233
|
+
key = (inference_service, model)
|
234
|
+
relevant_prices = price_lookup[key]
|
235
|
+
output_price_per_token = 1 / float(relevant_prices["output"]["one_usd_buys"])
|
236
|
+
input_price_per_token = 1 / float(relevant_prices["input"]["one_usd_buys"])
|
228
237
|
|
229
|
-
|
238
|
+
# Compute the number of characters (double if the question involves piping)
|
239
|
+
user_prompt_chars = len(str(user_prompt)) * get_piping_multiplier(
|
240
|
+
str(user_prompt)
|
241
|
+
)
|
242
|
+
system_prompt_chars = len(str(system_prompt)) * get_piping_multiplier(
|
243
|
+
str(system_prompt)
|
244
|
+
)
|
230
245
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
246
|
+
# Convert into tokens (1 token approx. equals 4 characters)
|
247
|
+
input_tokens = (user_prompt_chars + system_prompt_chars) // 4
|
248
|
+
output_tokens = input_tokens
|
249
|
+
|
250
|
+
cost = (
|
251
|
+
input_tokens * input_price_per_token
|
252
|
+
+ output_tokens * output_price_per_token
|
253
|
+
)
|
254
|
+
|
255
|
+
return {
|
256
|
+
"input_tokens": input_tokens,
|
257
|
+
"output_tokens": output_tokens,
|
258
|
+
"cost": cost,
|
259
|
+
}
|
260
|
+
|
261
|
+
def estimate_job_cost_from_external_prices(self, price_lookup: dict):
|
262
|
+
"""
|
263
|
+
Estimates the cost of a job according to the following assumptions:
|
264
|
+
|
265
|
+
- 1 token = 4 characters.
|
266
|
+
- Input tokens = output tokens.
|
267
|
+
|
268
|
+
price_lookup is an external pricing dictionary.
|
269
|
+
"""
|
270
|
+
|
271
|
+
import pandas as pd
|
272
|
+
|
273
|
+
interviews = self.interviews()
|
274
|
+
data = []
|
275
|
+
for interview in interviews:
|
276
|
+
invigilators = [
|
277
|
+
interview._get_invigilator(question)
|
278
|
+
for question in self.survey.questions
|
279
|
+
]
|
280
|
+
for invigilator in invigilators:
|
281
|
+
prompts = invigilator.get_prompts()
|
282
|
+
|
283
|
+
# By this point, agent and scenario data has already been added to the prompts
|
284
|
+
user_prompt = prompts["user_prompt"]
|
285
|
+
system_prompt = prompts["system_prompt"]
|
286
|
+
inference_service = invigilator.model._inference_service_
|
287
|
+
model = invigilator.model.model
|
288
|
+
|
289
|
+
prompt_cost = self.estimate_prompt_cost(
|
290
|
+
system_prompt=system_prompt,
|
291
|
+
user_prompt=user_prompt,
|
292
|
+
price_lookup=price_lookup,
|
293
|
+
inference_service=inference_service,
|
294
|
+
model=model,
|
295
|
+
)
|
296
|
+
|
297
|
+
data.append(
|
298
|
+
{
|
299
|
+
"user_prompt": user_prompt,
|
300
|
+
"system_prompt": system_prompt,
|
301
|
+
"estimated_input_tokens": prompt_cost["input_tokens"],
|
302
|
+
"estimated_output_tokens": prompt_cost["output_tokens"],
|
303
|
+
"estimated_cost": prompt_cost["cost"],
|
304
|
+
"inference_service": inference_service,
|
305
|
+
"model": model,
|
306
|
+
}
|
307
|
+
)
|
308
|
+
|
309
|
+
df = pd.DataFrame.from_records(data)
|
310
|
+
|
311
|
+
df = (
|
312
|
+
df.groupby(["inference_service", "model"])
|
313
|
+
.agg(
|
314
|
+
{
|
315
|
+
"estimated_cost": "sum",
|
316
|
+
"estimated_input_tokens": "sum",
|
317
|
+
"estimated_output_tokens": "sum",
|
318
|
+
}
|
319
|
+
)
|
320
|
+
.reset_index()
|
321
|
+
)
|
322
|
+
|
323
|
+
estimated_costs_by_model = df.to_dict("records")
|
324
|
+
|
325
|
+
estimated_total_cost = sum(
|
326
|
+
model["estimated_cost"] for model in estimated_costs_by_model
|
327
|
+
)
|
328
|
+
estimated_total_input_tokens = sum(
|
329
|
+
model["estimated_input_tokens"] for model in estimated_costs_by_model
|
330
|
+
)
|
331
|
+
estimated_total_output_tokens = sum(
|
332
|
+
model["estimated_output_tokens"] for model in estimated_costs_by_model
|
333
|
+
)
|
334
|
+
|
335
|
+
output = {
|
336
|
+
"estimated_total_cost": estimated_total_cost,
|
337
|
+
"estimated_total_input_tokens": estimated_total_input_tokens,
|
338
|
+
"estimated_total_output_tokens": estimated_total_output_tokens,
|
339
|
+
"model_costs": estimated_costs_by_model,
|
258
340
|
}
|
259
341
|
|
260
|
-
return
|
342
|
+
return output
|
343
|
+
|
344
|
+
def estimate_job_cost(self):
|
345
|
+
"""
|
346
|
+
Estimates the cost of a job according to the following assumptions:
|
347
|
+
|
348
|
+
- 1 token = 4 characters.
|
349
|
+
- Input tokens = output tokens.
|
350
|
+
|
351
|
+
Fetches prices from Coop.
|
352
|
+
"""
|
353
|
+
from edsl import Coop
|
354
|
+
|
355
|
+
c = Coop()
|
356
|
+
price_lookup = c.fetch_prices()
|
357
|
+
|
358
|
+
return self.estimate_job_cost_from_external_prices(price_lookup=price_lookup)
|
261
359
|
|
262
360
|
@staticmethod
|
263
361
|
def _get_container_class(object):
|
@@ -28,7 +28,7 @@ from edsl.jobs.interviews.InterviewExceptionCollection import (
|
|
28
28
|
InterviewExceptionCollection,
|
29
29
|
)
|
30
30
|
|
31
|
-
from edsl.jobs.interviews.InterviewStatusMixin import InterviewStatusMixin
|
31
|
+
# from edsl.jobs.interviews.InterviewStatusMixin import InterviewStatusMixin
|
32
32
|
|
33
33
|
from edsl.surveys.base import EndOfSurvey
|
34
34
|
from edsl.jobs.buckets.ModelBuckets import ModelBuckets
|
@@ -44,6 +44,10 @@ from edsl.agents.InvigilatorBase import InvigilatorBase
|
|
44
44
|
|
45
45
|
from edsl.exceptions.language_models import LanguageModelNoResponseError
|
46
46
|
|
47
|
+
from edsl.jobs.interviews.InterviewStatusLog import InterviewStatusLog
|
48
|
+
from edsl.jobs.tokens.InterviewTokenUsage import InterviewTokenUsage
|
49
|
+
from edsl.jobs.interviews.InterviewStatusDictionary import InterviewStatusDictionary
|
50
|
+
|
47
51
|
|
48
52
|
from edsl import CONFIG
|
49
53
|
|
@@ -52,7 +56,7 @@ EDSL_BACKOFF_MAX_SEC = float(CONFIG.get("EDSL_BACKOFF_MAX_SEC"))
|
|
52
56
|
EDSL_MAX_ATTEMPTS = int(CONFIG.get("EDSL_MAX_ATTEMPTS"))
|
53
57
|
|
54
58
|
|
55
|
-
class Interview
|
59
|
+
class Interview:
|
56
60
|
"""
|
57
61
|
An 'interview' is one agent answering one survey, with one language model, for a given scenario.
|
58
62
|
|
@@ -100,21 +104,17 @@ class Interview(InterviewStatusMixin):
|
|
100
104
|
|
101
105
|
"""
|
102
106
|
self.agent = agent
|
103
|
-
|
104
|
-
self.survey = copy.deepcopy(survey) # survey copy.deepcopy(survey)
|
105
|
-
# self.survey = survey
|
107
|
+
self.survey = copy.deepcopy(survey)
|
106
108
|
self.scenario = scenario
|
107
109
|
self.model = model
|
108
110
|
self.debug = debug
|
109
111
|
self.iteration = iteration
|
110
112
|
self.cache = cache
|
111
|
-
self.answers: dict[
|
112
|
-
|
113
|
-
|
113
|
+
self.answers: dict[str, str] = (
|
114
|
+
Answers()
|
115
|
+
) # will get filled in as interview progresses
|
114
116
|
self.sidecar_model = sidecar_model
|
115
117
|
|
116
|
-
# self.stop_on_exception = False
|
117
|
-
|
118
118
|
# Trackers
|
119
119
|
self.task_creators = TaskCreators() # tracks the task creators
|
120
120
|
self.exceptions = InterviewExceptionCollection()
|
@@ -131,6 +131,33 @@ class Interview(InterviewStatusMixin):
|
|
131
131
|
|
132
132
|
self.failed_questions = []
|
133
133
|
|
134
|
+
@property
|
135
|
+
def has_exceptions(self) -> bool:
|
136
|
+
"""Return True if there are exceptions."""
|
137
|
+
return len(self.exceptions) > 0
|
138
|
+
|
139
|
+
@property
|
140
|
+
def task_status_logs(self) -> InterviewStatusLog:
|
141
|
+
"""Return the task status logs for the interview.
|
142
|
+
|
143
|
+
The keys are the question names; the values are the lists of status log changes for each task.
|
144
|
+
"""
|
145
|
+
for task_creator in self.task_creators.values():
|
146
|
+
self._task_status_log_dict[task_creator.question.question_name] = (
|
147
|
+
task_creator.status_log
|
148
|
+
)
|
149
|
+
return self._task_status_log_dict
|
150
|
+
|
151
|
+
@property
|
152
|
+
def token_usage(self) -> InterviewTokenUsage:
|
153
|
+
"""Determine how many tokens were used for the interview."""
|
154
|
+
return self.task_creators.token_usage
|
155
|
+
|
156
|
+
@property
|
157
|
+
def interview_status(self) -> InterviewStatusDictionary:
|
158
|
+
"""Return a dictionary mapping task status codes to counts."""
|
159
|
+
return self.task_creators.interview_status
|
160
|
+
|
134
161
|
# region: Serialization
|
135
162
|
def _to_dict(self, include_exceptions=False) -> dict[str, Any]:
|
136
163
|
"""Return a dictionary representation of the Interview instance.
|
@@ -431,11 +458,11 @@ class Interview(InterviewStatusMixin):
|
|
431
458
|
"""
|
432
459
|
current_question_index: int = self.to_index[current_question.question_name]
|
433
460
|
|
434
|
-
next_question: Union[
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
461
|
+
next_question: Union[int, EndOfSurvey] = (
|
462
|
+
self.survey.rule_collection.next_question(
|
463
|
+
q_now=current_question_index,
|
464
|
+
answers=self.answers | self.scenario | self.agent["traits"],
|
465
|
+
)
|
439
466
|
)
|
440
467
|
|
441
468
|
next_question_index = next_question.next_q
|
@@ -1,20 +1,16 @@
|
|
1
1
|
import asyncio
|
2
2
|
from typing import Callable, Union, List
|
3
3
|
from collections import UserList, UserDict
|
4
|
-
import time
|
5
4
|
|
6
5
|
from edsl.jobs.buckets import ModelBuckets
|
7
6
|
from edsl.exceptions import InterviewErrorPriorTaskCanceled
|
8
7
|
|
9
8
|
from edsl.jobs.interviews.InterviewStatusDictionary import InterviewStatusDictionary
|
10
9
|
from edsl.jobs.tasks.task_status_enum import TaskStatus, TaskStatusDescriptor
|
11
|
-
|
12
|
-
# from edsl.jobs.tasks.task_management import TokensUsed
|
13
10
|
from edsl.jobs.tasks.TaskStatusLog import TaskStatusLog
|
14
11
|
from edsl.jobs.tokens.InterviewTokenUsage import InterviewTokenUsage
|
15
12
|
from edsl.jobs.tokens.TokenUsage import TokenUsage
|
16
13
|
from edsl.jobs.Answers import Answers
|
17
|
-
|
18
14
|
from edsl.questions.QuestionBase import QuestionBase
|
19
15
|
|
20
16
|
|
@@ -130,7 +126,7 @@ class QuestionTaskCreator(UserList):
|
|
130
126
|
await self.tokens_bucket.get_tokens(requested_tokens)
|
131
127
|
|
132
128
|
if (estimated_wait_time := self.requests_bucket.wait_time(1)) > 0:
|
133
|
-
self.waiting = True
|
129
|
+
self.waiting = True # do we need this?
|
134
130
|
self.task_status = TaskStatus.WAITING_FOR_REQUEST_CAPACITY
|
135
131
|
|
136
132
|
await self.requests_bucket.get_tokens(1, cheat_bucket_capacity=True)
|
@@ -348,6 +348,9 @@ class LanguageModel(
|
|
348
348
|
"""
|
349
349
|
# parameters = dict({})
|
350
350
|
|
351
|
+
# this is the case when data is loaded from a dict after serialization
|
352
|
+
if "parameters" in passed_parameter_dict:
|
353
|
+
passed_parameter_dict = passed_parameter_dict["parameters"]
|
351
354
|
return {
|
352
355
|
parameter_name: passed_parameter_dict.get(parameter_name, default_value)
|
353
356
|
for parameter_name, default_value in default_parameter_dict.items()
|