edsl 0.1.36.dev5__py3-none-any.whl → 0.1.36.dev7__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 +303 -303
- edsl/BaseDiff.py +260 -260
- edsl/TemplateLoader.py +24 -24
- edsl/__init__.py +48 -47
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +804 -804
- edsl/agents/AgentList.py +337 -337
- edsl/agents/Invigilator.py +222 -222
- edsl/agents/InvigilatorBase.py +298 -294
- edsl/agents/PromptConstructor.py +320 -312
- edsl/agents/__init__.py +3 -3
- edsl/agents/descriptors.py +86 -86
- edsl/agents/prompt_helpers.py +129 -129
- edsl/auto/AutoStudy.py +117 -117
- edsl/auto/StageBase.py +230 -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 +73 -73
- edsl/auto/SurveyCreatorPipeline.py +21 -21
- edsl/auto/utilities.py +224 -224
- edsl/base/Base.py +289 -289
- edsl/config.py +149 -149
- edsl/conjure/AgentConstructionMixin.py +152 -152
- edsl/conjure/Conjure.py +62 -62
- edsl/conjure/InputData.py +659 -659
- edsl/conjure/InputDataCSV.py +48 -48
- edsl/conjure/InputDataMixinQuestionStats.py +182 -182
- edsl/conjure/InputDataPyRead.py +91 -91
- edsl/conjure/InputDataSPSS.py +8 -8
- edsl/conjure/InputDataStata.py +8 -8
- edsl/conjure/QuestionOptionMixin.py +76 -76
- edsl/conjure/QuestionTypeMixin.py +23 -23
- edsl/conjure/RawQuestion.py +65 -65
- edsl/conjure/SurveyResponses.py +7 -7
- edsl/conjure/__init__.py +9 -9
- edsl/conjure/naming_utilities.py +263 -263
- edsl/conjure/utilities.py +201 -201
- edsl/conversation/Conversation.py +238 -238
- edsl/conversation/car_buying.py +58 -58
- edsl/conversation/mug_negotiation.py +81 -81
- edsl/conversation/next_speaker_utilities.py +93 -93
- edsl/coop/PriceFetcher.py +54 -54
- edsl/coop/__init__.py +2 -2
- edsl/coop/coop.py +849 -849
- edsl/coop/utils.py +131 -131
- edsl/data/Cache.py +527 -527
- edsl/data/CacheEntry.py +228 -228
- edsl/data/CacheHandler.py +149 -149
- edsl/data/RemoteCacheSync.py +83 -83
- edsl/data/SQLiteDict.py +292 -292
- edsl/data/__init__.py +4 -4
- edsl/data/orm.py +10 -10
- edsl/data_transfer_models.py +73 -73
- edsl/enums.py +173 -173
- edsl/exceptions/__init__.py +50 -50
- edsl/exceptions/agents.py +40 -40
- 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/jobs.py +33 -33
- edsl/exceptions/language_models.py +63 -63
- edsl/exceptions/prompts.py +15 -15
- edsl/exceptions/questions.py +91 -91
- edsl/exceptions/results.py +26 -26
- edsl/exceptions/surveys.py +34 -34
- edsl/inference_services/AnthropicService.py +87 -87
- edsl/inference_services/AwsBedrock.py +115 -115
- edsl/inference_services/AzureAI.py +217 -217
- edsl/inference_services/DeepInfraService.py +18 -18
- edsl/inference_services/GoogleService.py +156 -156
- edsl/inference_services/GroqService.py +20 -20
- edsl/inference_services/InferenceServiceABC.py +147 -147
- edsl/inference_services/InferenceServicesCollection.py +74 -68
- edsl/inference_services/MistralAIService.py +123 -123
- edsl/inference_services/OllamaService.py +18 -18
- edsl/inference_services/OpenAIService.py +224 -224
- edsl/inference_services/TestService.py +89 -89
- edsl/inference_services/TogetherAIService.py +170 -170
- edsl/inference_services/models_available_cache.py +118 -94
- edsl/inference_services/rate_limits_cache.py +25 -25
- edsl/inference_services/registry.py +39 -39
- edsl/inference_services/write_available.py +10 -10
- edsl/jobs/Answers.py +56 -56
- edsl/jobs/Jobs.py +1112 -1112
- edsl/jobs/__init__.py +1 -1
- edsl/jobs/buckets/BucketCollection.py +63 -63
- edsl/jobs/buckets/ModelBuckets.py +65 -65
- edsl/jobs/buckets/TokenBucket.py +248 -248
- edsl/jobs/interviews/Interview.py +661 -651
- edsl/jobs/interviews/InterviewExceptionCollection.py +99 -99
- edsl/jobs/interviews/InterviewExceptionEntry.py +189 -182
- 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/runners/JobsRunnerAsyncio.py +337 -337
- edsl/jobs/runners/JobsRunnerStatus.py +332 -332
- edsl/jobs/tasks/QuestionTaskCreator.py +242 -242
- edsl/jobs/tasks/TaskCreators.py +64 -64
- edsl/jobs/tasks/TaskHistory.py +441 -441
- edsl/jobs/tasks/TaskStatusLog.py +23 -23
- edsl/jobs/tasks/task_status_enum.py +163 -163
- edsl/jobs/tokens/InterviewTokenUsage.py +27 -27
- edsl/jobs/tokens/TokenUsage.py +34 -34
- edsl/language_models/LanguageModel.py +718 -718
- edsl/language_models/ModelList.py +102 -102
- edsl/language_models/RegisterLanguageModelsMeta.py +184 -184
- edsl/language_models/__init__.py +2 -2
- edsl/language_models/fake_openai_call.py +15 -15
- edsl/language_models/fake_openai_service.py +61 -61
- edsl/language_models/registry.py +137 -137
- edsl/language_models/repair.py +156 -156
- edsl/language_models/unused/ReplicateBase.py +83 -83
- edsl/language_models/utilities.py +64 -64
- edsl/notebooks/Notebook.py +259 -259
- edsl/notebooks/__init__.py +1 -1
- edsl/prompts/Prompt.py +358 -358
- edsl/prompts/__init__.py +2 -2
- edsl/questions/AnswerValidatorMixin.py +289 -289
- edsl/questions/QuestionBase.py +616 -616
- edsl/questions/QuestionBaseGenMixin.py +161 -161
- edsl/questions/QuestionBasePromptsMixin.py +266 -266
- edsl/questions/QuestionBudget.py +227 -227
- edsl/questions/QuestionCheckBox.py +359 -359
- edsl/questions/QuestionExtract.py +183 -183
- edsl/questions/QuestionFreeText.py +113 -113
- edsl/questions/QuestionFunctional.py +159 -159
- edsl/questions/QuestionList.py +231 -231
- edsl/questions/QuestionMultipleChoice.py +286 -286
- edsl/questions/QuestionNumerical.py +153 -153
- edsl/questions/QuestionRank.py +324 -324
- edsl/questions/Quick.py +41 -41
- edsl/questions/RegisterQuestionsMeta.py +71 -71
- edsl/questions/ResponseValidatorABC.py +174 -174
- edsl/questions/SimpleAskMixin.py +73 -73
- edsl/questions/__init__.py +26 -26
- edsl/questions/compose_questions.py +98 -98
- edsl/questions/decorators.py +21 -21
- edsl/questions/derived/QuestionLikertFive.py +76 -76
- edsl/questions/derived/QuestionLinearScale.py +87 -87
- edsl/questions/derived/QuestionTopK.py +91 -91
- edsl/questions/derived/QuestionYesNo.py +82 -82
- edsl/questions/descriptors.py +418 -418
- 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/question_registry.py +147 -147
- 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/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/Dataset.py +293 -293
- edsl/results/DatasetExportMixin.py +693 -693
- edsl/results/DatasetTree.py +145 -145
- edsl/results/Result.py +433 -433
- edsl/results/Results.py +1158 -1158
- edsl/results/ResultsDBMixin.py +238 -238
- edsl/results/ResultsExportMixin.py +43 -43
- edsl/results/ResultsFetchMixin.py +33 -33
- edsl/results/ResultsGGMixin.py +121 -121
- edsl/results/ResultsToolsMixin.py +98 -98
- edsl/results/Selector.py +118 -118
- edsl/results/__init__.py +2 -2
- edsl/results/tree_explore.py +115 -115
- edsl/scenarios/FileStore.py +458 -443
- edsl/scenarios/Scenario.py +510 -507
- edsl/scenarios/ScenarioHtmlMixin.py +59 -59
- edsl/scenarios/ScenarioList.py +1101 -1101
- edsl/scenarios/ScenarioListExportMixin.py +52 -52
- edsl/scenarios/ScenarioListPdfMixin.py +261 -261
- edsl/scenarios/__init__.py +4 -2
- 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 +528 -528
- edsl/study/__init__.py +4 -4
- edsl/surveys/DAG.py +148 -148
- edsl/surveys/Memory.py +31 -31
- edsl/surveys/MemoryPlan.py +244 -244
- edsl/surveys/Rule.py +324 -324
- edsl/surveys/RuleCollection.py +387 -387
- edsl/surveys/Survey.py +1772 -1772
- edsl/surveys/SurveyCSS.py +261 -261
- edsl/surveys/SurveyExportMixin.py +259 -259
- edsl/surveys/SurveyFlowVisualizationMixin.py +121 -121
- edsl/surveys/SurveyQualtricsImport.py +284 -284
- edsl/surveys/__init__.py +3 -3
- edsl/surveys/base.py +53 -53
- edsl/surveys/descriptors.py +56 -56
- edsl/surveys/instructions/ChangeInstruction.py +47 -47
- edsl/surveys/instructions/Instruction.py +51 -51
- edsl/surveys/instructions/InstructionCollection.py +77 -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 +9 -9
- 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/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/repair_functions.py +28 -28
- edsl/utilities/restricted_python.py +70 -70
- edsl/utilities/utilities.py +391 -391
- {edsl-0.1.36.dev5.dist-info → edsl-0.1.36.dev7.dist-info}/LICENSE +21 -21
- {edsl-0.1.36.dev5.dist-info → edsl-0.1.36.dev7.dist-info}/METADATA +1 -1
- edsl-0.1.36.dev7.dist-info/RECORD +279 -0
- edsl-0.1.36.dev5.dist-info/RECORD +0 -279
- {edsl-0.1.36.dev5.dist-info → edsl-0.1.36.dev7.dist-info}/WHEEL +0 -0
edsl/agents/__init__.py
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
from edsl.agents.Agent import Agent
|
2
|
-
from edsl.agents.AgentList import AgentList
|
3
|
-
from edsl.agents.InvigilatorBase import InvigilatorBase
|
1
|
+
from edsl.agents.Agent import Agent
|
2
|
+
from edsl.agents.AgentList import AgentList
|
3
|
+
from edsl.agents.InvigilatorBase import InvigilatorBase
|
edsl/agents/descriptors.py
CHANGED
@@ -1,86 +1,86 @@
|
|
1
|
-
"""This module contains the descriptors used to set the attributes of the Agent class."""
|
2
|
-
|
3
|
-
from typing import Dict
|
4
|
-
from edsl.exceptions.agents import AgentNameError, AgentTraitKeyError
|
5
|
-
|
6
|
-
|
7
|
-
class NameDescriptor:
|
8
|
-
"""ABC for something."""
|
9
|
-
|
10
|
-
def __get__(self, instance, owner):
|
11
|
-
"""Return the value of the attribute."""
|
12
|
-
return instance.__dict__[self.name]
|
13
|
-
|
14
|
-
def __set__(self, instance, name: str) -> None:
|
15
|
-
"""Set the value of the attribute."""
|
16
|
-
instance.__dict__[self.name] = name
|
17
|
-
|
18
|
-
def __set_name__(self, owner, name: str) -> None:
|
19
|
-
"""Set the name of the attribute."""
|
20
|
-
self.name = "_" + name
|
21
|
-
|
22
|
-
|
23
|
-
class TraitsDescriptor:
|
24
|
-
"""Traits descriptor."""
|
25
|
-
|
26
|
-
def __get__(self, instance, owner):
|
27
|
-
"""Return the value of the attribute."""
|
28
|
-
return instance.__dict__[self.name]
|
29
|
-
|
30
|
-
def __set__(self, instance, traits_dict: Dict[str, str]) -> None:
|
31
|
-
"""Set the value of the attribute."""
|
32
|
-
from edsl.utilities.utilities import is_valid_variable_name
|
33
|
-
|
34
|
-
for key, value in traits_dict.items():
|
35
|
-
if key == "name":
|
36
|
-
raise AgentNameError(
|
37
|
-
"""Trait keys cannot be 'name'. Instead, use the 'name' attribute directly e.g.,
|
38
|
-
Agent(name="my_agent", traits={"trait1": "value1", "trait2": "value2"})
|
39
|
-
"""
|
40
|
-
)
|
41
|
-
|
42
|
-
if not is_valid_variable_name(key):
|
43
|
-
raise AgentTraitKeyError(
|
44
|
-
f"""Trait keys must be valid Python identifiers (must be alphanumeric, cannot start with a number and must use underscores instead of spaces).
|
45
|
-
You passed: {key}
|
46
|
-
"""
|
47
|
-
)
|
48
|
-
|
49
|
-
instance.__dict__[self.name] = traits_dict
|
50
|
-
|
51
|
-
def __set_name__(self, owner, name: str) -> None:
|
52
|
-
"""Set the name of the attribute."""
|
53
|
-
self.name = name
|
54
|
-
|
55
|
-
|
56
|
-
class CodebookDescriptor:
|
57
|
-
"""ABC for something."""
|
58
|
-
|
59
|
-
def __get__(self, instance, owner):
|
60
|
-
"""Return the value of the attribute."""
|
61
|
-
return instance.__dict__[self.name]
|
62
|
-
|
63
|
-
def __set__(self, instance, codebook_dict: Dict[str, str]) -> None:
|
64
|
-
"""Set the value of the attribute."""
|
65
|
-
instance.__dict__[self.name] = codebook_dict
|
66
|
-
|
67
|
-
def __set_name__(self, owner, name: str) -> None:
|
68
|
-
"""Set the name of the attribute."""
|
69
|
-
self.name = "_" + name
|
70
|
-
|
71
|
-
|
72
|
-
class InstructionDescriptor:
|
73
|
-
"""ABC for something."""
|
74
|
-
|
75
|
-
def __get__(self, instance, owner):
|
76
|
-
"""Return the value of the attribute."""
|
77
|
-
return instance.__dict__[self.name]
|
78
|
-
|
79
|
-
def __set__(self, instance, instruction) -> None:
|
80
|
-
"""Set the value of the attribute."""
|
81
|
-
instance.__dict__[self.name] = instruction
|
82
|
-
instance.set_instructions = instruction != instance.default_instruction
|
83
|
-
|
84
|
-
def __set_name__(self, owner, name: str) -> None:
|
85
|
-
"""Set the name of the attribute."""
|
86
|
-
self.name = "_" + name
|
1
|
+
"""This module contains the descriptors used to set the attributes of the Agent class."""
|
2
|
+
|
3
|
+
from typing import Dict
|
4
|
+
from edsl.exceptions.agents import AgentNameError, AgentTraitKeyError
|
5
|
+
|
6
|
+
|
7
|
+
class NameDescriptor:
|
8
|
+
"""ABC for something."""
|
9
|
+
|
10
|
+
def __get__(self, instance, owner):
|
11
|
+
"""Return the value of the attribute."""
|
12
|
+
return instance.__dict__[self.name]
|
13
|
+
|
14
|
+
def __set__(self, instance, name: str) -> None:
|
15
|
+
"""Set the value of the attribute."""
|
16
|
+
instance.__dict__[self.name] = name
|
17
|
+
|
18
|
+
def __set_name__(self, owner, name: str) -> None:
|
19
|
+
"""Set the name of the attribute."""
|
20
|
+
self.name = "_" + name
|
21
|
+
|
22
|
+
|
23
|
+
class TraitsDescriptor:
|
24
|
+
"""Traits descriptor."""
|
25
|
+
|
26
|
+
def __get__(self, instance, owner):
|
27
|
+
"""Return the value of the attribute."""
|
28
|
+
return instance.__dict__[self.name]
|
29
|
+
|
30
|
+
def __set__(self, instance, traits_dict: Dict[str, str]) -> None:
|
31
|
+
"""Set the value of the attribute."""
|
32
|
+
from edsl.utilities.utilities import is_valid_variable_name
|
33
|
+
|
34
|
+
for key, value in traits_dict.items():
|
35
|
+
if key == "name":
|
36
|
+
raise AgentNameError(
|
37
|
+
"""Trait keys cannot be 'name'. Instead, use the 'name' attribute directly e.g.,
|
38
|
+
Agent(name="my_agent", traits={"trait1": "value1", "trait2": "value2"})
|
39
|
+
"""
|
40
|
+
)
|
41
|
+
|
42
|
+
if not is_valid_variable_name(key):
|
43
|
+
raise AgentTraitKeyError(
|
44
|
+
f"""Trait keys must be valid Python identifiers (must be alphanumeric, cannot start with a number and must use underscores instead of spaces).
|
45
|
+
You passed: {key}
|
46
|
+
"""
|
47
|
+
)
|
48
|
+
|
49
|
+
instance.__dict__[self.name] = traits_dict
|
50
|
+
|
51
|
+
def __set_name__(self, owner, name: str) -> None:
|
52
|
+
"""Set the name of the attribute."""
|
53
|
+
self.name = name
|
54
|
+
|
55
|
+
|
56
|
+
class CodebookDescriptor:
|
57
|
+
"""ABC for something."""
|
58
|
+
|
59
|
+
def __get__(self, instance, owner):
|
60
|
+
"""Return the value of the attribute."""
|
61
|
+
return instance.__dict__[self.name]
|
62
|
+
|
63
|
+
def __set__(self, instance, codebook_dict: Dict[str, str]) -> None:
|
64
|
+
"""Set the value of the attribute."""
|
65
|
+
instance.__dict__[self.name] = codebook_dict
|
66
|
+
|
67
|
+
def __set_name__(self, owner, name: str) -> None:
|
68
|
+
"""Set the name of the attribute."""
|
69
|
+
self.name = "_" + name
|
70
|
+
|
71
|
+
|
72
|
+
class InstructionDescriptor:
|
73
|
+
"""ABC for something."""
|
74
|
+
|
75
|
+
def __get__(self, instance, owner):
|
76
|
+
"""Return the value of the attribute."""
|
77
|
+
return instance.__dict__[self.name]
|
78
|
+
|
79
|
+
def __set__(self, instance, instruction) -> None:
|
80
|
+
"""Set the value of the attribute."""
|
81
|
+
instance.__dict__[self.name] = instruction
|
82
|
+
instance.set_instructions = instruction != instance.default_instruction
|
83
|
+
|
84
|
+
def __set_name__(self, owner, name: str) -> None:
|
85
|
+
"""Set the name of the attribute."""
|
86
|
+
self.name = "_" + name
|
edsl/agents/prompt_helpers.py
CHANGED
@@ -1,129 +1,129 @@
|
|
1
|
-
import enum
|
2
|
-
from typing import Dict, Optional
|
3
|
-
from collections import UserList
|
4
|
-
from edsl.prompts import Prompt
|
5
|
-
|
6
|
-
|
7
|
-
class PromptComponent(enum.Enum):
|
8
|
-
AGENT_INSTRUCTIONS = "agent_instructions"
|
9
|
-
AGENT_PERSONA = "agent_persona"
|
10
|
-
QUESTION_INSTRUCTIONS = "question_instructions"
|
11
|
-
PRIOR_QUESTION_MEMORY = "prior_question_memory"
|
12
|
-
|
13
|
-
|
14
|
-
class PromptList(UserList):
|
15
|
-
separator = Prompt(" ")
|
16
|
-
|
17
|
-
def reduce(self):
|
18
|
-
"""Reduce the list of prompts to a single prompt.
|
19
|
-
|
20
|
-
>>> p = PromptList([Prompt("You are a happy-go lucky agent."), Prompt("You are an agent with the following persona: {'age': 22, 'hair': 'brown', 'height': 5.5}")])
|
21
|
-
>>> p.reduce()
|
22
|
-
Prompt(text=\"""You are a happy-go lucky agent. You are an agent with the following persona: {'age': 22, 'hair': 'brown', 'height': 5.5}\""")
|
23
|
-
|
24
|
-
"""
|
25
|
-
p = self[0]
|
26
|
-
for prompt in self[1:]:
|
27
|
-
if len(prompt) > 0:
|
28
|
-
p = p + self.separator + prompt
|
29
|
-
return p
|
30
|
-
|
31
|
-
|
32
|
-
class PromptPlan:
|
33
|
-
"""A plan for constructing prompts for the LLM call.
|
34
|
-
Every prompt plan has a user prompt order and a system prompt order.
|
35
|
-
It must contain each of the values in the PromptComponent enum.
|
36
|
-
|
37
|
-
|
38
|
-
>>> p = PromptPlan(user_prompt_order=(PromptComponent.AGENT_INSTRUCTIONS, PromptComponent.AGENT_PERSONA),system_prompt_order=(PromptComponent.QUESTION_INSTRUCTIONS, PromptComponent.PRIOR_QUESTION_MEMORY))
|
39
|
-
>>> p._is_valid_plan()
|
40
|
-
True
|
41
|
-
|
42
|
-
>>> p.arrange_components(agent_instructions=1, agent_persona=2, question_instructions=3, prior_question_memory=4)
|
43
|
-
{'user_prompt': ..., 'system_prompt': ...}
|
44
|
-
|
45
|
-
>>> p = PromptPlan(user_prompt_order=("agent_instructions", ), system_prompt_order=("question_instructions", "prior_question_memory"))
|
46
|
-
Traceback (most recent call last):
|
47
|
-
...
|
48
|
-
ValueError: Invalid plan: must contain each value of PromptComponent exactly once.
|
49
|
-
|
50
|
-
"""
|
51
|
-
|
52
|
-
def __init__(
|
53
|
-
self,
|
54
|
-
user_prompt_order: Optional[tuple] = None,
|
55
|
-
system_prompt_order: Optional[tuple] = None,
|
56
|
-
):
|
57
|
-
"""Initialize the PromptPlan."""
|
58
|
-
|
59
|
-
if user_prompt_order is None:
|
60
|
-
user_prompt_order = (
|
61
|
-
PromptComponent.QUESTION_INSTRUCTIONS,
|
62
|
-
PromptComponent.PRIOR_QUESTION_MEMORY,
|
63
|
-
)
|
64
|
-
if system_prompt_order is None:
|
65
|
-
system_prompt_order = (
|
66
|
-
PromptComponent.AGENT_INSTRUCTIONS,
|
67
|
-
PromptComponent.AGENT_PERSONA,
|
68
|
-
)
|
69
|
-
|
70
|
-
# very commmon way to screw this up given how python treats single strings as iterables
|
71
|
-
if isinstance(user_prompt_order, str):
|
72
|
-
user_prompt_order = (user_prompt_order,)
|
73
|
-
|
74
|
-
if isinstance(system_prompt_order, str):
|
75
|
-
system_prompt_order = (system_prompt_order,)
|
76
|
-
|
77
|
-
if not isinstance(user_prompt_order, tuple):
|
78
|
-
raise TypeError(
|
79
|
-
f"Expected a tuple, but got {type(user_prompt_order).__name__}"
|
80
|
-
)
|
81
|
-
|
82
|
-
if not isinstance(system_prompt_order, tuple):
|
83
|
-
raise TypeError(
|
84
|
-
f"Expected a tuple, but got {type(system_prompt_order).__name__}"
|
85
|
-
)
|
86
|
-
|
87
|
-
self.user_prompt_order = self._convert_to_enum(user_prompt_order)
|
88
|
-
self.system_prompt_order = self._convert_to_enum(system_prompt_order)
|
89
|
-
if not self._is_valid_plan():
|
90
|
-
raise ValueError(
|
91
|
-
"Invalid plan: must contain each value of PromptComponent exactly once."
|
92
|
-
)
|
93
|
-
|
94
|
-
def _convert_to_enum(self, prompt_order: tuple):
|
95
|
-
"""Convert string names to PromptComponent enum values."""
|
96
|
-
return tuple(
|
97
|
-
PromptComponent(component) if isinstance(component, str) else component
|
98
|
-
for component in prompt_order
|
99
|
-
)
|
100
|
-
|
101
|
-
def _is_valid_plan(self):
|
102
|
-
"""Check if the plan is valid."""
|
103
|
-
combined = self.user_prompt_order + self.system_prompt_order
|
104
|
-
return set(combined) == set(PromptComponent)
|
105
|
-
|
106
|
-
def arrange_components(self, **kwargs) -> Dict[PromptComponent, Prompt]:
|
107
|
-
"""Arrange the components in the order specified by the plan."""
|
108
|
-
# check is valid components passed
|
109
|
-
component_strings = set([pc.value for pc in PromptComponent])
|
110
|
-
if not set(kwargs.keys()) == component_strings:
|
111
|
-
raise ValueError(
|
112
|
-
f"Invalid components passed: {set(kwargs.keys())} but expected {PromptComponent}"
|
113
|
-
)
|
114
|
-
|
115
|
-
user_prompt = PromptList(
|
116
|
-
[kwargs[component.value] for component in self.user_prompt_order]
|
117
|
-
)
|
118
|
-
system_prompt = PromptList(
|
119
|
-
[kwargs[component.value] for component in self.system_prompt_order]
|
120
|
-
)
|
121
|
-
return {"user_prompt": user_prompt, "system_prompt": system_prompt}
|
122
|
-
|
123
|
-
def get_prompts(self, **kwargs) -> Dict[str, Prompt]:
|
124
|
-
"""Get both prompts for the LLM call."""
|
125
|
-
prompts = self.arrange_components(**kwargs)
|
126
|
-
return {
|
127
|
-
"user_prompt": prompts["user_prompt"].reduce(),
|
128
|
-
"system_prompt": prompts["system_prompt"].reduce(),
|
129
|
-
}
|
1
|
+
import enum
|
2
|
+
from typing import Dict, Optional
|
3
|
+
from collections import UserList
|
4
|
+
from edsl.prompts import Prompt
|
5
|
+
|
6
|
+
|
7
|
+
class PromptComponent(enum.Enum):
|
8
|
+
AGENT_INSTRUCTIONS = "agent_instructions"
|
9
|
+
AGENT_PERSONA = "agent_persona"
|
10
|
+
QUESTION_INSTRUCTIONS = "question_instructions"
|
11
|
+
PRIOR_QUESTION_MEMORY = "prior_question_memory"
|
12
|
+
|
13
|
+
|
14
|
+
class PromptList(UserList):
|
15
|
+
separator = Prompt(" ")
|
16
|
+
|
17
|
+
def reduce(self):
|
18
|
+
"""Reduce the list of prompts to a single prompt.
|
19
|
+
|
20
|
+
>>> p = PromptList([Prompt("You are a happy-go lucky agent."), Prompt("You are an agent with the following persona: {'age': 22, 'hair': 'brown', 'height': 5.5}")])
|
21
|
+
>>> p.reduce()
|
22
|
+
Prompt(text=\"""You are a happy-go lucky agent. You are an agent with the following persona: {'age': 22, 'hair': 'brown', 'height': 5.5}\""")
|
23
|
+
|
24
|
+
"""
|
25
|
+
p = self[0]
|
26
|
+
for prompt in self[1:]:
|
27
|
+
if len(prompt) > 0:
|
28
|
+
p = p + self.separator + prompt
|
29
|
+
return p
|
30
|
+
|
31
|
+
|
32
|
+
class PromptPlan:
|
33
|
+
"""A plan for constructing prompts for the LLM call.
|
34
|
+
Every prompt plan has a user prompt order and a system prompt order.
|
35
|
+
It must contain each of the values in the PromptComponent enum.
|
36
|
+
|
37
|
+
|
38
|
+
>>> p = PromptPlan(user_prompt_order=(PromptComponent.AGENT_INSTRUCTIONS, PromptComponent.AGENT_PERSONA),system_prompt_order=(PromptComponent.QUESTION_INSTRUCTIONS, PromptComponent.PRIOR_QUESTION_MEMORY))
|
39
|
+
>>> p._is_valid_plan()
|
40
|
+
True
|
41
|
+
|
42
|
+
>>> p.arrange_components(agent_instructions=1, agent_persona=2, question_instructions=3, prior_question_memory=4)
|
43
|
+
{'user_prompt': ..., 'system_prompt': ...}
|
44
|
+
|
45
|
+
>>> p = PromptPlan(user_prompt_order=("agent_instructions", ), system_prompt_order=("question_instructions", "prior_question_memory"))
|
46
|
+
Traceback (most recent call last):
|
47
|
+
...
|
48
|
+
ValueError: Invalid plan: must contain each value of PromptComponent exactly once.
|
49
|
+
|
50
|
+
"""
|
51
|
+
|
52
|
+
def __init__(
|
53
|
+
self,
|
54
|
+
user_prompt_order: Optional[tuple] = None,
|
55
|
+
system_prompt_order: Optional[tuple] = None,
|
56
|
+
):
|
57
|
+
"""Initialize the PromptPlan."""
|
58
|
+
|
59
|
+
if user_prompt_order is None:
|
60
|
+
user_prompt_order = (
|
61
|
+
PromptComponent.QUESTION_INSTRUCTIONS,
|
62
|
+
PromptComponent.PRIOR_QUESTION_MEMORY,
|
63
|
+
)
|
64
|
+
if system_prompt_order is None:
|
65
|
+
system_prompt_order = (
|
66
|
+
PromptComponent.AGENT_INSTRUCTIONS,
|
67
|
+
PromptComponent.AGENT_PERSONA,
|
68
|
+
)
|
69
|
+
|
70
|
+
# very commmon way to screw this up given how python treats single strings as iterables
|
71
|
+
if isinstance(user_prompt_order, str):
|
72
|
+
user_prompt_order = (user_prompt_order,)
|
73
|
+
|
74
|
+
if isinstance(system_prompt_order, str):
|
75
|
+
system_prompt_order = (system_prompt_order,)
|
76
|
+
|
77
|
+
if not isinstance(user_prompt_order, tuple):
|
78
|
+
raise TypeError(
|
79
|
+
f"Expected a tuple, but got {type(user_prompt_order).__name__}"
|
80
|
+
)
|
81
|
+
|
82
|
+
if not isinstance(system_prompt_order, tuple):
|
83
|
+
raise TypeError(
|
84
|
+
f"Expected a tuple, but got {type(system_prompt_order).__name__}"
|
85
|
+
)
|
86
|
+
|
87
|
+
self.user_prompt_order = self._convert_to_enum(user_prompt_order)
|
88
|
+
self.system_prompt_order = self._convert_to_enum(system_prompt_order)
|
89
|
+
if not self._is_valid_plan():
|
90
|
+
raise ValueError(
|
91
|
+
"Invalid plan: must contain each value of PromptComponent exactly once."
|
92
|
+
)
|
93
|
+
|
94
|
+
def _convert_to_enum(self, prompt_order: tuple):
|
95
|
+
"""Convert string names to PromptComponent enum values."""
|
96
|
+
return tuple(
|
97
|
+
PromptComponent(component) if isinstance(component, str) else component
|
98
|
+
for component in prompt_order
|
99
|
+
)
|
100
|
+
|
101
|
+
def _is_valid_plan(self):
|
102
|
+
"""Check if the plan is valid."""
|
103
|
+
combined = self.user_prompt_order + self.system_prompt_order
|
104
|
+
return set(combined) == set(PromptComponent)
|
105
|
+
|
106
|
+
def arrange_components(self, **kwargs) -> Dict[PromptComponent, Prompt]:
|
107
|
+
"""Arrange the components in the order specified by the plan."""
|
108
|
+
# check is valid components passed
|
109
|
+
component_strings = set([pc.value for pc in PromptComponent])
|
110
|
+
if not set(kwargs.keys()) == component_strings:
|
111
|
+
raise ValueError(
|
112
|
+
f"Invalid components passed: {set(kwargs.keys())} but expected {PromptComponent}"
|
113
|
+
)
|
114
|
+
|
115
|
+
user_prompt = PromptList(
|
116
|
+
[kwargs[component.value] for component in self.user_prompt_order]
|
117
|
+
)
|
118
|
+
system_prompt = PromptList(
|
119
|
+
[kwargs[component.value] for component in self.system_prompt_order]
|
120
|
+
)
|
121
|
+
return {"user_prompt": user_prompt, "system_prompt": system_prompt}
|
122
|
+
|
123
|
+
def get_prompts(self, **kwargs) -> Dict[str, Prompt]:
|
124
|
+
"""Get both prompts for the LLM call."""
|
125
|
+
prompts = self.arrange_components(**kwargs)
|
126
|
+
return {
|
127
|
+
"user_prompt": prompts["user_prompt"].reduce(),
|
128
|
+
"system_prompt": prompts["system_prompt"].reduce(),
|
129
|
+
}
|