edsl 0.1.39.dev3__py3-none-any.whl → 0.1.39.dev5__py3-none-any.whl
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/Base.py +413 -332
- edsl/BaseDiff.py +260 -260
- edsl/TemplateLoader.py +24 -24
- edsl/__init__.py +57 -49
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +1071 -867
- edsl/agents/AgentList.py +551 -413
- edsl/agents/Invigilator.py +284 -233
- edsl/agents/InvigilatorBase.py +257 -270
- edsl/agents/PromptConstructor.py +272 -354
- edsl/agents/QuestionInstructionPromptBuilder.py +128 -0
- edsl/agents/QuestionTemplateReplacementsBuilder.py +137 -0
- edsl/agents/__init__.py +2 -3
- edsl/agents/descriptors.py +99 -99
- edsl/agents/prompt_helpers.py +129 -129
- edsl/agents/question_option_processor.py +172 -0
- edsl/auto/AutoStudy.py +130 -117
- edsl/auto/StageBase.py +243 -230
- edsl/auto/StageGenerateSurvey.py +178 -178
- edsl/auto/StageLabelQuestions.py +125 -125
- edsl/auto/StagePersona.py +61 -61
- edsl/auto/StagePersonaDimensionValueRanges.py +88 -88
- edsl/auto/StagePersonaDimensionValues.py +74 -74
- edsl/auto/StagePersonaDimensions.py +69 -69
- edsl/auto/StageQuestions.py +74 -73
- edsl/auto/SurveyCreatorPipeline.py +21 -21
- edsl/auto/utilities.py +218 -224
- edsl/base/Base.py +279 -279
- edsl/config.py +177 -157
- edsl/conversation/Conversation.py +290 -290
- edsl/conversation/car_buying.py +59 -58
- edsl/conversation/chips.py +95 -95
- edsl/conversation/mug_negotiation.py +81 -81
- edsl/conversation/next_speaker_utilities.py +93 -93
- edsl/coop/CoopFunctionsMixin.py +15 -0
- edsl/coop/ExpectedParrotKeyHandler.py +125 -0
- edsl/coop/PriceFetcher.py +54 -54
- edsl/coop/__init__.py +2 -2
- edsl/coop/coop.py +1106 -1028
- edsl/coop/utils.py +131 -131
- edsl/data/Cache.py +573 -555
- edsl/data/CacheEntry.py +230 -233
- edsl/data/CacheHandler.py +168 -149
- edsl/data/RemoteCacheSync.py +186 -78
- edsl/data/SQLiteDict.py +292 -292
- edsl/data/__init__.py +5 -4
- edsl/data/orm.py +10 -10
- edsl/data_transfer_models.py +74 -73
- edsl/enums.py +202 -175
- edsl/exceptions/BaseException.py +21 -21
- edsl/exceptions/__init__.py +54 -54
- edsl/exceptions/agents.py +54 -42
- edsl/exceptions/cache.py +5 -5
- edsl/exceptions/configuration.py +16 -16
- edsl/exceptions/coop.py +10 -10
- edsl/exceptions/data.py +14 -14
- edsl/exceptions/general.py +34 -34
- edsl/exceptions/inference_services.py +5 -0
- edsl/exceptions/jobs.py +33 -33
- edsl/exceptions/language_models.py +63 -63
- edsl/exceptions/prompts.py +15 -15
- edsl/exceptions/questions.py +109 -91
- edsl/exceptions/results.py +29 -29
- edsl/exceptions/scenarios.py +29 -22
- edsl/exceptions/surveys.py +37 -37
- edsl/inference_services/AnthropicService.py +106 -87
- edsl/inference_services/AvailableModelCacheHandler.py +184 -0
- edsl/inference_services/AvailableModelFetcher.py +215 -0
- edsl/inference_services/AwsBedrock.py +118 -120
- edsl/inference_services/AzureAI.py +215 -217
- edsl/inference_services/DeepInfraService.py +18 -18
- edsl/inference_services/GoogleService.py +143 -148
- edsl/inference_services/GroqService.py +20 -20
- edsl/inference_services/InferenceServiceABC.py +80 -147
- edsl/inference_services/InferenceServicesCollection.py +138 -97
- edsl/inference_services/MistralAIService.py +120 -123
- edsl/inference_services/OllamaService.py +18 -18
- edsl/inference_services/OpenAIService.py +236 -224
- edsl/inference_services/PerplexityService.py +160 -163
- edsl/inference_services/ServiceAvailability.py +135 -0
- edsl/inference_services/TestService.py +90 -89
- edsl/inference_services/TogetherAIService.py +172 -170
- edsl/inference_services/data_structures.py +134 -0
- edsl/inference_services/models_available_cache.py +118 -118
- edsl/inference_services/rate_limits_cache.py +25 -25
- edsl/inference_services/registry.py +41 -41
- edsl/inference_services/write_available.py +10 -10
- edsl/jobs/AnswerQuestionFunctionConstructor.py +223 -0
- edsl/jobs/Answers.py +43 -56
- edsl/jobs/FetchInvigilator.py +47 -0
- edsl/jobs/InterviewTaskManager.py +98 -0
- edsl/jobs/InterviewsConstructor.py +50 -0
- edsl/jobs/Jobs.py +823 -898
- edsl/jobs/JobsChecks.py +172 -147
- edsl/jobs/JobsComponentConstructor.py +189 -0
- edsl/jobs/JobsPrompts.py +270 -268
- edsl/jobs/JobsRemoteInferenceHandler.py +311 -239
- edsl/jobs/JobsRemoteInferenceLogger.py +239 -0
- edsl/jobs/RequestTokenEstimator.py +30 -0
- edsl/jobs/__init__.py +1 -1
- edsl/jobs/async_interview_runner.py +138 -0
- edsl/jobs/buckets/BucketCollection.py +104 -63
- edsl/jobs/buckets/ModelBuckets.py +65 -65
- edsl/jobs/buckets/TokenBucket.py +283 -251
- edsl/jobs/buckets/TokenBucketAPI.py +211 -0
- edsl/jobs/buckets/TokenBucketClient.py +191 -0
- edsl/jobs/check_survey_scenario_compatibility.py +85 -0
- edsl/jobs/data_structures.py +120 -0
- edsl/jobs/decorators.py +35 -0
- edsl/jobs/interviews/Interview.py +396 -661
- edsl/jobs/interviews/InterviewExceptionCollection.py +99 -99
- edsl/jobs/interviews/InterviewExceptionEntry.py +186 -186
- edsl/jobs/interviews/InterviewStatistic.py +63 -63
- edsl/jobs/interviews/InterviewStatisticsCollection.py +25 -25
- edsl/jobs/interviews/InterviewStatusDictionary.py +78 -78
- edsl/jobs/interviews/InterviewStatusLog.py +92 -92
- edsl/jobs/interviews/ReportErrors.py +66 -66
- edsl/jobs/interviews/interview_status_enum.py +9 -9
- edsl/jobs/jobs_status_enums.py +9 -0
- edsl/jobs/loggers/HTMLTableJobLogger.py +304 -0
- edsl/jobs/results_exceptions_handler.py +98 -0
- edsl/jobs/runners/JobsRunnerAsyncio.py +151 -466
- edsl/jobs/runners/JobsRunnerStatus.py +297 -330
- edsl/jobs/tasks/QuestionTaskCreator.py +244 -242
- edsl/jobs/tasks/TaskCreators.py +64 -64
- edsl/jobs/tasks/TaskHistory.py +470 -450
- edsl/jobs/tasks/TaskStatusLog.py +23 -23
- edsl/jobs/tasks/task_status_enum.py +161 -163
- edsl/jobs/tokens/InterviewTokenUsage.py +27 -27
- edsl/jobs/tokens/TokenUsage.py +34 -34
- edsl/language_models/ComputeCost.py +63 -0
- edsl/language_models/LanguageModel.py +626 -668
- edsl/language_models/ModelList.py +164 -155
- edsl/language_models/PriceManager.py +127 -0
- edsl/language_models/RawResponseHandler.py +106 -0
- edsl/language_models/RegisterLanguageModelsMeta.py +184 -184
- edsl/language_models/ServiceDataSources.py +0 -0
- edsl/language_models/__init__.py +2 -3
- edsl/language_models/fake_openai_call.py +15 -15
- edsl/language_models/fake_openai_service.py +61 -61
- edsl/language_models/key_management/KeyLookup.py +63 -0
- edsl/language_models/key_management/KeyLookupBuilder.py +273 -0
- edsl/language_models/key_management/KeyLookupCollection.py +38 -0
- edsl/language_models/key_management/__init__.py +0 -0
- edsl/language_models/key_management/models.py +131 -0
- edsl/language_models/model.py +256 -0
- edsl/language_models/repair.py +156 -156
- edsl/language_models/utilities.py +65 -64
- edsl/notebooks/Notebook.py +263 -258
- edsl/notebooks/NotebookToLaTeX.py +142 -0
- edsl/notebooks/__init__.py +1 -1
- edsl/prompts/Prompt.py +352 -362
- edsl/prompts/__init__.py +2 -2
- edsl/questions/ExceptionExplainer.py +77 -0
- edsl/questions/HTMLQuestion.py +103 -0
- edsl/questions/QuestionBase.py +518 -664
- edsl/questions/QuestionBasePromptsMixin.py +221 -217
- edsl/questions/QuestionBudget.py +227 -227
- edsl/questions/QuestionCheckBox.py +359 -359
- edsl/questions/QuestionExtract.py +180 -182
- edsl/questions/QuestionFreeText.py +113 -114
- edsl/questions/QuestionFunctional.py +166 -166
- edsl/questions/QuestionList.py +223 -231
- edsl/questions/QuestionMatrix.py +265 -0
- edsl/questions/QuestionMultipleChoice.py +330 -286
- edsl/questions/QuestionNumerical.py +151 -153
- edsl/questions/QuestionRank.py +314 -324
- edsl/questions/Quick.py +41 -41
- edsl/questions/SimpleAskMixin.py +74 -73
- edsl/questions/__init__.py +27 -26
- edsl/questions/{AnswerValidatorMixin.py → answer_validator_mixin.py} +334 -289
- edsl/questions/compose_questions.py +98 -98
- edsl/questions/data_structures.py +20 -0
- edsl/questions/decorators.py +21 -21
- edsl/questions/derived/QuestionLikertFive.py +76 -76
- edsl/questions/derived/QuestionLinearScale.py +90 -87
- edsl/questions/derived/QuestionTopK.py +93 -93
- edsl/questions/derived/QuestionYesNo.py +82 -82
- edsl/questions/descriptors.py +427 -413
- edsl/questions/loop_processor.py +149 -0
- edsl/questions/prompt_templates/question_budget.jinja +13 -13
- edsl/questions/prompt_templates/question_checkbox.jinja +32 -32
- edsl/questions/prompt_templates/question_extract.jinja +11 -11
- edsl/questions/prompt_templates/question_free_text.jinja +3 -3
- edsl/questions/prompt_templates/question_linear_scale.jinja +11 -11
- edsl/questions/prompt_templates/question_list.jinja +17 -17
- edsl/questions/prompt_templates/question_multiple_choice.jinja +33 -33
- edsl/questions/prompt_templates/question_numerical.jinja +36 -36
- edsl/questions/{QuestionBaseGenMixin.py → question_base_gen_mixin.py} +168 -161
- edsl/questions/question_registry.py +177 -177
- edsl/questions/{RegisterQuestionsMeta.py → register_questions_meta.py} +71 -71
- edsl/questions/{ResponseValidatorABC.py → response_validator_abc.py} +188 -174
- edsl/questions/response_validator_factory.py +34 -0
- edsl/questions/settings.py +12 -12
- edsl/questions/templates/budget/answering_instructions.jinja +7 -7
- edsl/questions/templates/budget/question_presentation.jinja +7 -7
- edsl/questions/templates/checkbox/answering_instructions.jinja +10 -10
- edsl/questions/templates/checkbox/question_presentation.jinja +22 -22
- edsl/questions/templates/extract/answering_instructions.jinja +7 -7
- edsl/questions/templates/likert_five/answering_instructions.jinja +10 -10
- edsl/questions/templates/likert_five/question_presentation.jinja +11 -11
- edsl/questions/templates/linear_scale/answering_instructions.jinja +5 -5
- edsl/questions/templates/linear_scale/question_presentation.jinja +5 -5
- edsl/questions/templates/list/answering_instructions.jinja +3 -3
- edsl/questions/templates/list/question_presentation.jinja +5 -5
- edsl/questions/templates/matrix/__init__.py +1 -0
- edsl/questions/templates/matrix/answering_instructions.jinja +5 -0
- edsl/questions/templates/matrix/question_presentation.jinja +20 -0
- edsl/questions/templates/multiple_choice/answering_instructions.jinja +9 -9
- edsl/questions/templates/multiple_choice/question_presentation.jinja +11 -11
- edsl/questions/templates/numerical/answering_instructions.jinja +6 -6
- edsl/questions/templates/numerical/question_presentation.jinja +6 -6
- edsl/questions/templates/rank/answering_instructions.jinja +11 -11
- edsl/questions/templates/rank/question_presentation.jinja +15 -15
- edsl/questions/templates/top_k/answering_instructions.jinja +8 -8
- edsl/questions/templates/top_k/question_presentation.jinja +22 -22
- edsl/questions/templates/yes_no/answering_instructions.jinja +6 -6
- edsl/questions/templates/yes_no/question_presentation.jinja +11 -11
- edsl/results/CSSParameterizer.py +108 -108
- edsl/results/Dataset.py +587 -424
- edsl/results/DatasetExportMixin.py +594 -731
- edsl/results/DatasetTree.py +295 -275
- edsl/results/MarkdownToDocx.py +122 -0
- edsl/results/MarkdownToPDF.py +111 -0
- edsl/results/Result.py +557 -465
- edsl/results/Results.py +1183 -1165
- edsl/results/ResultsExportMixin.py +45 -43
- edsl/results/ResultsGGMixin.py +121 -121
- edsl/results/TableDisplay.py +125 -198
- edsl/results/TextEditor.py +50 -0
- edsl/results/__init__.py +2 -2
- edsl/results/file_exports.py +252 -0
- edsl/results/{ResultsFetchMixin.py → results_fetch_mixin.py} +33 -33
- edsl/results/{Selector.py → results_selector.py} +145 -135
- edsl/results/{ResultsToolsMixin.py → results_tools_mixin.py} +98 -98
- edsl/results/smart_objects.py +96 -0
- edsl/results/table_data_class.py +12 -0
- edsl/results/table_display.css +77 -77
- edsl/results/table_renderers.py +118 -0
- edsl/results/tree_explore.py +115 -115
- edsl/scenarios/ConstructDownloadLink.py +109 -0
- edsl/scenarios/DocumentChunker.py +102 -0
- edsl/scenarios/DocxScenario.py +16 -0
- edsl/scenarios/FileStore.py +511 -632
- edsl/scenarios/PdfExtractor.py +40 -0
- edsl/scenarios/Scenario.py +498 -601
- edsl/scenarios/ScenarioHtmlMixin.py +65 -64
- edsl/scenarios/ScenarioList.py +1458 -1287
- edsl/scenarios/ScenarioListExportMixin.py +45 -52
- edsl/scenarios/ScenarioListPdfMixin.py +239 -261
- edsl/scenarios/__init__.py +3 -4
- edsl/scenarios/directory_scanner.py +96 -0
- edsl/scenarios/file_methods.py +85 -0
- edsl/scenarios/handlers/__init__.py +13 -0
- edsl/scenarios/handlers/csv.py +38 -0
- edsl/scenarios/handlers/docx.py +76 -0
- edsl/scenarios/handlers/html.py +37 -0
- edsl/scenarios/handlers/json.py +111 -0
- edsl/scenarios/handlers/latex.py +5 -0
- edsl/scenarios/handlers/md.py +51 -0
- edsl/scenarios/handlers/pdf.py +68 -0
- edsl/scenarios/handlers/png.py +39 -0
- edsl/scenarios/handlers/pptx.py +105 -0
- edsl/scenarios/handlers/py.py +294 -0
- edsl/scenarios/handlers/sql.py +313 -0
- edsl/scenarios/handlers/sqlite.py +149 -0
- edsl/scenarios/handlers/txt.py +33 -0
- edsl/scenarios/{ScenarioJoin.py → scenario_join.py} +131 -127
- edsl/scenarios/scenario_selector.py +156 -0
- edsl/shared.py +1 -1
- edsl/study/ObjectEntry.py +173 -173
- edsl/study/ProofOfWork.py +113 -113
- edsl/study/SnapShot.py +80 -80
- edsl/study/Study.py +521 -528
- edsl/study/__init__.py +4 -4
- edsl/surveys/ConstructDAG.py +92 -0
- edsl/surveys/DAG.py +148 -148
- edsl/surveys/EditSurvey.py +221 -0
- edsl/surveys/InstructionHandler.py +100 -0
- edsl/surveys/Memory.py +31 -31
- edsl/surveys/MemoryManagement.py +72 -0
- edsl/surveys/MemoryPlan.py +244 -244
- edsl/surveys/Rule.py +327 -326
- edsl/surveys/RuleCollection.py +385 -387
- edsl/surveys/RuleManager.py +172 -0
- edsl/surveys/Simulator.py +75 -0
- edsl/surveys/Survey.py +1280 -1801
- edsl/surveys/SurveyCSS.py +273 -261
- edsl/surveys/SurveyExportMixin.py +259 -259
- edsl/surveys/{SurveyFlowVisualizationMixin.py → SurveyFlowVisualization.py} +181 -179
- edsl/surveys/SurveyQualtricsImport.py +284 -284
- edsl/surveys/SurveyToApp.py +141 -0
- edsl/surveys/__init__.py +5 -3
- edsl/surveys/base.py +53 -53
- edsl/surveys/descriptors.py +60 -56
- edsl/surveys/instructions/ChangeInstruction.py +48 -49
- edsl/surveys/instructions/Instruction.py +56 -65
- edsl/surveys/instructions/InstructionCollection.py +82 -77
- edsl/templates/error_reporting/base.html +23 -23
- edsl/templates/error_reporting/exceptions_by_model.html +34 -34
- edsl/templates/error_reporting/exceptions_by_question_name.html +16 -16
- edsl/templates/error_reporting/exceptions_by_type.html +16 -16
- edsl/templates/error_reporting/interview_details.html +115 -115
- edsl/templates/error_reporting/interviews.html +19 -19
- edsl/templates/error_reporting/overview.html +4 -4
- edsl/templates/error_reporting/performance_plot.html +1 -1
- edsl/templates/error_reporting/report.css +73 -73
- edsl/templates/error_reporting/report.html +117 -117
- edsl/templates/error_reporting/report.js +25 -25
- edsl/tools/__init__.py +1 -1
- edsl/tools/clusters.py +192 -192
- edsl/tools/embeddings.py +27 -27
- edsl/tools/embeddings_plotting.py +118 -118
- edsl/tools/plotting.py +112 -112
- edsl/tools/summarize.py +18 -18
- edsl/utilities/PrettyList.py +56 -0
- edsl/utilities/SystemInfo.py +28 -28
- edsl/utilities/__init__.py +22 -22
- edsl/utilities/ast_utilities.py +25 -25
- edsl/utilities/data/Registry.py +6 -6
- edsl/utilities/data/__init__.py +1 -1
- edsl/utilities/data/scooter_results.json +1 -1
- edsl/utilities/decorators.py +77 -77
- edsl/utilities/gcp_bucket/cloud_storage.py +96 -96
- edsl/utilities/interface.py +627 -627
- edsl/utilities/is_notebook.py +18 -0
- edsl/utilities/is_valid_variable_name.py +11 -0
- edsl/utilities/naming_utilities.py +263 -263
- edsl/utilities/remove_edsl_version.py +24 -0
- edsl/utilities/repair_functions.py +28 -28
- edsl/utilities/restricted_python.py +70 -70
- edsl/utilities/utilities.py +436 -424
- {edsl-0.1.39.dev3.dist-info → edsl-0.1.39.dev5.dist-info}/LICENSE +21 -21
- {edsl-0.1.39.dev3.dist-info → edsl-0.1.39.dev5.dist-info}/METADATA +13 -11
- edsl-0.1.39.dev5.dist-info/RECORD +358 -0
- {edsl-0.1.39.dev3.dist-info → edsl-0.1.39.dev5.dist-info}/WHEEL +1 -1
- edsl/language_models/KeyLookup.py +0 -30
- edsl/language_models/registry.py +0 -190
- edsl/language_models/unused/ReplicateBase.py +0 -83
- edsl/results/ResultsDBMixin.py +0 -238
- edsl-0.1.39.dev3.dist-info/RECORD +0 -277
edsl/agents/InvigilatorBase.py
CHANGED
@@ -1,270 +1,257 @@
|
|
1
|
-
from abc import ABC, abstractmethod
|
2
|
-
import asyncio
|
3
|
-
from typing import Coroutine, Dict, Any, Optional
|
4
|
-
|
5
|
-
from edsl.
|
6
|
-
from edsl.
|
7
|
-
|
8
|
-
|
9
|
-
from edsl.
|
10
|
-
|
11
|
-
from edsl.questions.QuestionBase import QuestionBase
|
12
|
-
from edsl.scenarios.Scenario import Scenario
|
13
|
-
from edsl.surveys.MemoryPlan import MemoryPlan
|
14
|
-
from edsl.language_models.LanguageModel import LanguageModel
|
15
|
-
|
16
|
-
from edsl.
|
17
|
-
from edsl.
|
18
|
-
|
19
|
-
from edsl.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
"""
|
35
|
-
|
36
|
-
def __init__(
|
37
|
-
self,
|
38
|
-
agent: "Agent",
|
39
|
-
question: QuestionBase,
|
40
|
-
scenario: Scenario,
|
41
|
-
model: LanguageModel,
|
42
|
-
memory_plan: MemoryPlan,
|
43
|
-
current_answers: dict,
|
44
|
-
survey: Optional["Survey"],
|
45
|
-
cache: Optional[Cache] = None,
|
46
|
-
iteration: Optional[int] = 1,
|
47
|
-
additional_prompt_data: Optional[dict] = None,
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
):
|
52
|
-
"""Initialize a new Invigilator."""
|
53
|
-
self.agent = agent
|
54
|
-
self.question = question
|
55
|
-
self.scenario = scenario
|
56
|
-
self.model = model
|
57
|
-
self.memory_plan = memory_plan
|
58
|
-
self.current_answers = current_answers or {}
|
59
|
-
self.iteration = iteration
|
60
|
-
self.additional_prompt_data = additional_prompt_data
|
61
|
-
self.cache = cache
|
62
|
-
self.
|
63
|
-
self.
|
64
|
-
self.
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
@property
|
75
|
-
def prompt_constructor(self) -> PromptConstructor:
|
76
|
-
"""Return the prompt constructor."""
|
77
|
-
return PromptConstructor(self, prompt_plan=self.prompt_plan)
|
78
|
-
|
79
|
-
def to_dict(self, include_cache=False):
|
80
|
-
attributes = [
|
81
|
-
"agent",
|
82
|
-
"question",
|
83
|
-
"scenario",
|
84
|
-
"model",
|
85
|
-
"memory_plan",
|
86
|
-
"current_answers",
|
87
|
-
"iteration",
|
88
|
-
"additional_prompt_data",
|
89
|
-
"
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
value
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
from edsl.
|
110
|
-
from edsl.
|
111
|
-
from edsl.
|
112
|
-
from edsl.
|
113
|
-
from edsl.
|
114
|
-
from edsl.
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
data
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
"
|
175
|
-
"
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
from edsl.
|
215
|
-
from edsl.
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
if
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
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
|
-
|
258
|
-
question=question,
|
259
|
-
scenario=scenario,
|
260
|
-
survey=survey,
|
261
|
-
model=model,
|
262
|
-
memory_plan=memory_plan,
|
263
|
-
current_answers=current_answers,
|
264
|
-
)
|
265
|
-
|
266
|
-
|
267
|
-
if __name__ == "__main__":
|
268
|
-
import doctest
|
269
|
-
|
270
|
-
doctest.testmod(optionflags=doctest.ELLIPSIS)
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
import asyncio
|
3
|
+
from typing import Coroutine, Dict, Any, Optional, TYPE_CHECKING
|
4
|
+
|
5
|
+
from edsl.utilities.decorators import jupyter_nb_handler
|
6
|
+
from edsl.data_transfer_models import AgentResponseDict
|
7
|
+
|
8
|
+
if TYPE_CHECKING:
|
9
|
+
from edsl.prompts.Prompt import Prompt
|
10
|
+
from edsl.data.Cache import Cache
|
11
|
+
from edsl.questions.QuestionBase import QuestionBase
|
12
|
+
from edsl.scenarios.Scenario import Scenario
|
13
|
+
from edsl.surveys.MemoryPlan import MemoryPlan
|
14
|
+
from edsl.language_models.LanguageModel import LanguageModel
|
15
|
+
from edsl.surveys.Survey import Survey
|
16
|
+
from edsl.agents.Agent import Agent
|
17
|
+
from edsl.language_models.key_management.KeyLookup import KeyLookup
|
18
|
+
|
19
|
+
from edsl.data_transfer_models import EDSLResultObjectInput
|
20
|
+
from edsl.agents.PromptConstructor import PromptConstructor
|
21
|
+
from edsl.agents.prompt_helpers import PromptPlan
|
22
|
+
|
23
|
+
|
24
|
+
class InvigilatorBase(ABC):
|
25
|
+
"""An invigiator (someone who administers an exam) is a class that is responsible for administering a question to an agent.
|
26
|
+
|
27
|
+
>>> InvigilatorBase.example().answer_question()
|
28
|
+
{'message': [{'text': 'SPAM!'}], 'usage': {'prompt_tokens': 1, 'completion_tokens': 1}}
|
29
|
+
|
30
|
+
>>> InvigilatorBase.example().get_failed_task_result(failure_reason="Failed to get response").comment
|
31
|
+
'Failed to get response'
|
32
|
+
|
33
|
+
This returns an empty prompt because there is no memory the agent needs to have at q0.
|
34
|
+
"""
|
35
|
+
|
36
|
+
def __init__(
|
37
|
+
self,
|
38
|
+
agent: "Agent",
|
39
|
+
question: "QuestionBase",
|
40
|
+
scenario: "Scenario",
|
41
|
+
model: "LanguageModel",
|
42
|
+
memory_plan: "MemoryPlan",
|
43
|
+
current_answers: dict,
|
44
|
+
survey: Optional["Survey"],
|
45
|
+
cache: Optional["Cache"] = None,
|
46
|
+
iteration: Optional[int] = 1,
|
47
|
+
additional_prompt_data: Optional[dict] = None,
|
48
|
+
raise_validation_errors: Optional[bool] = True,
|
49
|
+
prompt_plan: Optional["PromptPlan"] = None,
|
50
|
+
key_lookup: Optional["KeyLookup"] = None,
|
51
|
+
):
|
52
|
+
"""Initialize a new Invigilator."""
|
53
|
+
self.agent = agent
|
54
|
+
self.question = question
|
55
|
+
self.scenario = scenario
|
56
|
+
self.model = model
|
57
|
+
self.memory_plan = memory_plan
|
58
|
+
self.current_answers = current_answers or {}
|
59
|
+
self.iteration = iteration
|
60
|
+
self.additional_prompt_data = additional_prompt_data
|
61
|
+
self.cache = cache
|
62
|
+
self.survey = survey
|
63
|
+
self.raise_validation_errors = raise_validation_errors
|
64
|
+
self.key_lookup = key_lookup
|
65
|
+
|
66
|
+
if prompt_plan is None:
|
67
|
+
self.prompt_plan = PromptPlan()
|
68
|
+
else:
|
69
|
+
self.prompt_plan = prompt_plan
|
70
|
+
|
71
|
+
# placeholder to store the raw model response
|
72
|
+
self.raw_model_response = None
|
73
|
+
|
74
|
+
@property
|
75
|
+
def prompt_constructor(self) -> PromptConstructor:
|
76
|
+
"""Return the prompt constructor."""
|
77
|
+
return PromptConstructor(self, prompt_plan=self.prompt_plan)
|
78
|
+
|
79
|
+
def to_dict(self, include_cache=False) -> Dict[str, Any]:
|
80
|
+
attributes = [
|
81
|
+
"agent",
|
82
|
+
"question",
|
83
|
+
"scenario",
|
84
|
+
"model",
|
85
|
+
"memory_plan",
|
86
|
+
"current_answers",
|
87
|
+
"iteration",
|
88
|
+
"additional_prompt_data",
|
89
|
+
"survey",
|
90
|
+
]
|
91
|
+
if include_cache:
|
92
|
+
attributes.append("cache")
|
93
|
+
|
94
|
+
def serialize_attribute(attr):
|
95
|
+
value = getattr(self, attr)
|
96
|
+
if value is None:
|
97
|
+
return None
|
98
|
+
if hasattr(value, "to_dict"):
|
99
|
+
return value.to_dict()
|
100
|
+
if isinstance(value, (int, float, str, bool, dict, list)):
|
101
|
+
return value
|
102
|
+
return str(value)
|
103
|
+
|
104
|
+
return {attr: serialize_attribute(attr) for attr in attributes}
|
105
|
+
|
106
|
+
@classmethod
|
107
|
+
def from_dict(cls, data) -> "InvigilatorBase":
|
108
|
+
from edsl.agents.Agent import Agent
|
109
|
+
from edsl.questions import QuestionBase
|
110
|
+
from edsl.scenarios.Scenario import Scenario
|
111
|
+
from edsl.surveys.MemoryPlan import MemoryPlan
|
112
|
+
from edsl.language_models.LanguageModel import LanguageModel
|
113
|
+
from edsl.surveys.Survey import Survey
|
114
|
+
from edsl.data.Cache import Cache
|
115
|
+
|
116
|
+
attributes_to_classes = {
|
117
|
+
"agent": Agent,
|
118
|
+
"question": QuestionBase,
|
119
|
+
"scenario": Scenario,
|
120
|
+
"model": LanguageModel,
|
121
|
+
"memory_plan": MemoryPlan,
|
122
|
+
"survey": Survey,
|
123
|
+
"cache": Cache,
|
124
|
+
}
|
125
|
+
d = {}
|
126
|
+
for attr, cls_ in attributes_to_classes.items():
|
127
|
+
if attr in data and data[attr] is not None:
|
128
|
+
if attr not in data:
|
129
|
+
d[attr] = {}
|
130
|
+
else:
|
131
|
+
d[attr] = cls_.from_dict(data[attr])
|
132
|
+
|
133
|
+
d["current_answers"] = data["current_answers"]
|
134
|
+
d["iteration"] = data["iteration"]
|
135
|
+
d["additional_prompt_data"] = data["additional_prompt_data"]
|
136
|
+
|
137
|
+
d = cls(**d)
|
138
|
+
|
139
|
+
def __repr__(self) -> str:
|
140
|
+
"""Return a string representation of the Invigilator.
|
141
|
+
|
142
|
+
>>> InvigilatorBase.example().__repr__()
|
143
|
+
'InvigilatorExample(...)'
|
144
|
+
|
145
|
+
"""
|
146
|
+
return f"{self.__class__.__name__}(agent={repr(self.agent)}, question={repr(self.question)}, scneario={repr(self.scenario)}, model={repr(self.model)}, memory_plan={repr(self.memory_plan)}, current_answers={repr(self.current_answers)}, iteration{repr(self.iteration)}, additional_prompt_data={repr(self.additional_prompt_data)}, cache={repr(self.cache)})"
|
147
|
+
|
148
|
+
def get_failed_task_result(self, failure_reason: str) -> EDSLResultObjectInput:
|
149
|
+
"""Return an AgentResponseDict used in case the question-asking fails.
|
150
|
+
|
151
|
+
Possible reasons include:
|
152
|
+
- Legimately skipped because of skip logic
|
153
|
+
- Failed to get response from the model
|
154
|
+
|
155
|
+
"""
|
156
|
+
data = {
|
157
|
+
"answer": None,
|
158
|
+
"generated_tokens": None,
|
159
|
+
"comment": failure_reason,
|
160
|
+
"question_name": self.question.question_name,
|
161
|
+
"prompts": self.get_prompts(),
|
162
|
+
"cached_response": None,
|
163
|
+
"raw_model_response": None,
|
164
|
+
"cache_used": None,
|
165
|
+
"cache_key": None,
|
166
|
+
}
|
167
|
+
return EDSLResultObjectInput(**data)
|
168
|
+
|
169
|
+
def get_prompts(self) -> Dict[str, "Prompt"]:
|
170
|
+
"""Return the prompt used."""
|
171
|
+
from edsl.prompts.Prompt import Prompt
|
172
|
+
|
173
|
+
return {
|
174
|
+
"user_prompt": Prompt("NA"),
|
175
|
+
"system_prompt": Prompt("NA"),
|
176
|
+
}
|
177
|
+
|
178
|
+
@abstractmethod
|
179
|
+
async def async_answer_question(self):
|
180
|
+
"""Asnwer a question."""
|
181
|
+
pass
|
182
|
+
|
183
|
+
@jupyter_nb_handler
|
184
|
+
def answer_question(self) -> Coroutine:
|
185
|
+
"""Return a function that gets the answers to the question."""
|
186
|
+
|
187
|
+
async def main():
|
188
|
+
"""Return the answer to the question."""
|
189
|
+
results = await asyncio.gather(self.async_answer_question())
|
190
|
+
return results[0] # Since there's only one task, return its result
|
191
|
+
|
192
|
+
return main()
|
193
|
+
|
194
|
+
@classmethod
|
195
|
+
def example(
|
196
|
+
cls, throw_an_exception=False, question=None, scenario=None, survey=None
|
197
|
+
) -> "InvigilatorBase":
|
198
|
+
"""Return an example invigilator.
|
199
|
+
|
200
|
+
>>> InvigilatorBase.example()
|
201
|
+
InvigilatorExample(...)
|
202
|
+
|
203
|
+
>>> InvigilatorBase.example().answer_question()
|
204
|
+
{'message': [{'text': 'SPAM!'}], 'usage': {'prompt_tokens': 1, 'completion_tokens': 1}}
|
205
|
+
|
206
|
+
>>> InvigilatorBase.example(throw_an_exception=True).answer_question()
|
207
|
+
Traceback (most recent call last):
|
208
|
+
...
|
209
|
+
Exception: This is a test error
|
210
|
+
"""
|
211
|
+
from edsl.agents.Agent import Agent
|
212
|
+
from edsl.scenarios.Scenario import Scenario
|
213
|
+
from edsl.surveys.MemoryPlan import MemoryPlan
|
214
|
+
from edsl.language_models.model import Model
|
215
|
+
from edsl.surveys.Survey import Survey
|
216
|
+
|
217
|
+
model = Model("test", canned_response="SPAM!")
|
218
|
+
|
219
|
+
if throw_an_exception:
|
220
|
+
model.throw_exception = True
|
221
|
+
agent = Agent.example()
|
222
|
+
|
223
|
+
if not survey:
|
224
|
+
survey = Survey.example()
|
225
|
+
|
226
|
+
if question not in survey.questions and question is not None:
|
227
|
+
survey.add_question(question)
|
228
|
+
|
229
|
+
question = question or survey.questions[0]
|
230
|
+
scenario = scenario or Scenario.example()
|
231
|
+
memory_plan = MemoryPlan(survey=survey)
|
232
|
+
current_answers = None
|
233
|
+
|
234
|
+
class InvigilatorExample(cls):
|
235
|
+
"""An example invigilator."""
|
236
|
+
|
237
|
+
async def async_answer_question(self):
|
238
|
+
"""Answer a question."""
|
239
|
+
return await self.model.async_execute_model_call(
|
240
|
+
user_prompt="Hello", system_prompt="Hi"
|
241
|
+
)
|
242
|
+
|
243
|
+
return InvigilatorExample(
|
244
|
+
agent=agent,
|
245
|
+
question=question,
|
246
|
+
scenario=scenario,
|
247
|
+
survey=survey,
|
248
|
+
model=model,
|
249
|
+
memory_plan=memory_plan,
|
250
|
+
current_answers=current_answers,
|
251
|
+
)
|
252
|
+
|
253
|
+
|
254
|
+
if __name__ == "__main__":
|
255
|
+
import doctest
|
256
|
+
|
257
|
+
doctest.testmod(optionflags=doctest.ELLIPSIS)
|