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/auto/StageQuestions.py
CHANGED
@@ -1,73 +1,74 @@
|
|
1
|
-
from dataclasses import dataclass
|
2
|
-
from typing import List
|
3
|
-
from textwrap import dedent
|
4
|
-
|
5
|
-
|
6
|
-
from edsl import Scenario
|
7
|
-
from edsl import Model
|
8
|
-
from edsl.questions.QuestionList import QuestionList
|
9
|
-
|
10
|
-
from edsl.auto.StageBase import StageBase
|
11
|
-
from edsl.auto.StageBase import FlowDataBase
|
12
|
-
|
13
|
-
from edsl.auto.utilities import gen_pipeline
|
14
|
-
|
15
|
-
|
16
|
-
class StageQuestions(StageBase):
|
17
|
-
"This stages takes as input an overall question and returns a list of questions"
|
18
|
-
|
19
|
-
@dataclass
|
20
|
-
class Input(FlowDataBase):
|
21
|
-
overall_question: str
|
22
|
-
population: str
|
23
|
-
|
24
|
-
@dataclass
|
25
|
-
class Output(FlowDataBase):
|
26
|
-
questions: List[str]
|
27
|
-
population: str
|
28
|
-
|
29
|
-
input = Input
|
30
|
-
output = Output
|
31
|
-
|
32
|
-
def handle_data(self, data):
|
33
|
-
m = Model()
|
34
|
-
overall_question = data.overall_question
|
35
|
-
population = data.population
|
36
|
-
s = Scenario({"overall_question": overall_question, "population": population})
|
37
|
-
q = QuestionList(
|
38
|
-
question_text=dedent(
|
39
|
-
"""\
|
40
|
-
Suppose I am interested in the question:
|
41
|
-
"{{ overall_question }}"
|
42
|
-
What would be some survey questions I could ask to {{ population }} that might shed light on this question?
|
43
|
-
"""
|
44
|
-
),
|
45
|
-
question_name="questions",
|
46
|
-
)
|
47
|
-
results = q.by(s).by(m).run()
|
48
|
-
(
|
49
|
-
results.select("questions").print(
|
50
|
-
pretty_labels={
|
51
|
-
"answer.questions": f'Questions for overall question: "{overall_question }"'
|
52
|
-
},
|
53
|
-
split_at_dot=False,
|
54
|
-
)
|
55
|
-
)
|
56
|
-
|
57
|
-
raw_questions = results.select("questions").first()
|
58
|
-
questions = [q.replace("'", "").replace(":", "") for q in raw_questions]
|
59
|
-
return self.Output(questions=questions, population=population)
|
60
|
-
|
61
|
-
|
62
|
-
if __name__ == "__main__":
|
63
|
-
pipeline = gen_pipeline([StageQuestions])
|
64
|
-
|
65
|
-
pipeline.process(
|
66
|
-
pipeline.input(
|
67
|
-
overall_question="What are some factors that could determine whether someone likes ice cream?",
|
68
|
-
population="Consumers",
|
69
|
-
)
|
70
|
-
)
|
71
|
-
|
72
|
-
|
73
|
-
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import List
|
3
|
+
from textwrap import dedent
|
4
|
+
|
5
|
+
|
6
|
+
from edsl import Scenario
|
7
|
+
from edsl import Model
|
8
|
+
from edsl.questions.QuestionList import QuestionList
|
9
|
+
|
10
|
+
from edsl.auto.StageBase import StageBase
|
11
|
+
from edsl.auto.StageBase import FlowDataBase
|
12
|
+
|
13
|
+
from edsl.auto.utilities import gen_pipeline
|
14
|
+
|
15
|
+
|
16
|
+
class StageQuestions(StageBase):
|
17
|
+
"This stages takes as input an overall question and returns a list of questions"
|
18
|
+
|
19
|
+
@dataclass
|
20
|
+
class Input(FlowDataBase):
|
21
|
+
overall_question: str
|
22
|
+
population: str
|
23
|
+
|
24
|
+
@dataclass
|
25
|
+
class Output(FlowDataBase):
|
26
|
+
questions: List[str]
|
27
|
+
population: str
|
28
|
+
|
29
|
+
input = Input
|
30
|
+
output = Output
|
31
|
+
|
32
|
+
def handle_data(self, data):
|
33
|
+
m = Model()
|
34
|
+
overall_question = data.overall_question
|
35
|
+
population = data.population
|
36
|
+
s = Scenario({"overall_question": overall_question, "population": population})
|
37
|
+
q = QuestionList(
|
38
|
+
question_text=dedent(
|
39
|
+
"""\
|
40
|
+
Suppose I am interested in the question:
|
41
|
+
"{{ overall_question }}"
|
42
|
+
What would be some survey questions I could ask to {{ population }} that might shed light on this question?
|
43
|
+
"""
|
44
|
+
),
|
45
|
+
question_name="questions",
|
46
|
+
)
|
47
|
+
results = q.by(s).by(m).run()
|
48
|
+
(
|
49
|
+
results.select("questions").print(
|
50
|
+
pretty_labels={
|
51
|
+
"answer.questions": f'Questions for overall question: "{overall_question }"'
|
52
|
+
},
|
53
|
+
split_at_dot=False,
|
54
|
+
)
|
55
|
+
)
|
56
|
+
|
57
|
+
raw_questions = results.select("questions").first()
|
58
|
+
questions = [q.replace("'", "").replace(":", "") for q in raw_questions]
|
59
|
+
return self.Output(questions=questions, population=population)
|
60
|
+
|
61
|
+
|
62
|
+
if __name__ == "__main__":
|
63
|
+
pipeline = gen_pipeline([StageQuestions])
|
64
|
+
|
65
|
+
pipeline.process(
|
66
|
+
pipeline.input(
|
67
|
+
overall_question="What are some factors that could determine whether someone likes ice cream?",
|
68
|
+
population="Consumers",
|
69
|
+
)
|
70
|
+
)
|
71
|
+
|
72
|
+
results = StageQuestions.func(
|
73
|
+
overall_question="Why aren't my students studying more?", population="Tech"
|
74
|
+
)
|
@@ -1,21 +1,21 @@
|
|
1
|
-
import random
|
2
|
-
from typing import Dict, List, Any, TypeVar, Generator, Optional
|
3
|
-
|
4
|
-
from textwrap import dedent
|
5
|
-
|
6
|
-
# from edsl.language_models.model_interfaces.LanguageModelOpenAIFour import LanguageModelOpenAIFour
|
7
|
-
from edsl import Model
|
8
|
-
from edsl.agents.AgentList import AgentList
|
9
|
-
from edsl.results.Results import Results
|
10
|
-
from edsl import Agent
|
11
|
-
|
12
|
-
from edsl import Scenario
|
13
|
-
from edsl.surveys.Survey import Survey
|
14
|
-
|
15
|
-
from edsl.questions.QuestionMultipleChoice import QuestionMultipleChoice
|
16
|
-
from edsl.questions.QuestionFreeText import QuestionFreeText
|
17
|
-
from edsl.auto.utilities import gen_pipeline
|
18
|
-
from edsl.utilities.naming_utilities import sanitize_string
|
19
|
-
|
20
|
-
|
21
|
-
m = Model()
|
1
|
+
import random
|
2
|
+
from typing import Dict, List, Any, TypeVar, Generator, Optional
|
3
|
+
|
4
|
+
from textwrap import dedent
|
5
|
+
|
6
|
+
# from edsl.language_models.model_interfaces.LanguageModelOpenAIFour import LanguageModelOpenAIFour
|
7
|
+
from edsl import Model
|
8
|
+
from edsl.agents.AgentList import AgentList
|
9
|
+
from edsl.results.Results import Results
|
10
|
+
from edsl import Agent
|
11
|
+
|
12
|
+
from edsl import Scenario
|
13
|
+
from edsl.surveys.Survey import Survey
|
14
|
+
|
15
|
+
from edsl.questions.QuestionMultipleChoice import QuestionMultipleChoice
|
16
|
+
from edsl.questions.QuestionFreeText import QuestionFreeText
|
17
|
+
from edsl.auto.utilities import gen_pipeline
|
18
|
+
from edsl.utilities.naming_utilities import sanitize_string
|
19
|
+
|
20
|
+
|
21
|
+
m = Model()
|
edsl/auto/utilities.py
CHANGED
@@ -1,224 +1,218 @@
|
|
1
|
-
from textwrap import dedent
|
2
|
-
import random
|
3
|
-
from typing import List, TypeVar, Generator, Optional
|
4
|
-
from edsl.auto.StageBase import StageBase
|
5
|
-
from edsl.utilities.naming_utilities import sanitize_string
|
6
|
-
from edsl import Agent, Survey, Model, Cache, AgentList
|
7
|
-
from edsl import QuestionFreeText, Scenario
|
8
|
-
from edsl import QuestionMultipleChoice, Scenario, Agent, ScenarioList
|
9
|
-
|
10
|
-
StageClassType = TypeVar("StageClassType", bound=StageBase)
|
11
|
-
|
12
|
-
|
13
|
-
def gen_pipeline(stages_list: List[StageClassType]) -> StageBase:
|
14
|
-
"""Takes as input a list of Stage classes & returns a pipeline of instantiated stages.
|
15
|
-
A pipeline is a linked list of stages where each stage has a next_stage attribute.
|
16
|
-
|
17
|
-
"""
|
18
|
-
pipeline = stages_list[0]()
|
19
|
-
last_stage = pipeline
|
20
|
-
for stage in stages_list[1:]:
|
21
|
-
while last_stage.next_stage is not None: # find the end of the pipeline
|
22
|
-
last_stage = last_stage.next_stage
|
23
|
-
stage_to_add = stage()
|
24
|
-
last_stage.next_stage = stage_to_add
|
25
|
-
return pipeline
|
26
|
-
|
27
|
-
|
28
|
-
q_eligibility = QuestionMultipleChoice(
|
29
|
-
question_text=dedent(
|
30
|
-
"""\
|
31
|
-
Consider this set of question: '{{ questions }}'.
|
32
|
-
Consider this persona: '{{ persona }}'.
|
33
|
-
Would this persona be able to answer all of these questions?
|
34
|
-
"""
|
35
|
-
),
|
36
|
-
question_options=["No", "Yes"],
|
37
|
-
question_name="eligibility",
|
38
|
-
)
|
39
|
-
|
40
|
-
|
41
|
-
def agent_list_eligibility(
|
42
|
-
agent_list: AgentList,
|
43
|
-
survey: Optional[Survey] = None,
|
44
|
-
model: Optional[Model] = None,
|
45
|
-
cache: Optional[Cache] = None,
|
46
|
-
) -> List[bool]:
|
47
|
-
"""
|
48
|
-
Returns whether each agent in a list is elgible for a survey i.e., can answer every question.
|
49
|
-
|
50
|
-
>>> from edsl.language_models import LanguageModel
|
51
|
-
>>> m = LanguageModel.example(canned_response = "1", test_model = True)
|
52
|
-
>>> agent_list_eligibility(AgentList.example())
|
53
|
-
[True, True]
|
54
|
-
>>> agent_list_eligibility(AgentList.example().add_trait('persona', 2*["Cool dude"]), survey = Survey.example(), model = m)
|
55
|
-
[True, True]
|
56
|
-
"""
|
57
|
-
if survey is None:
|
58
|
-
return [True] * len(agent_list)
|
59
|
-
if "persona" not in agent_list.all_traits:
|
60
|
-
raise ValueError(
|
61
|
-
f"Each agent needs to have a persona attribute; traits are {agent_list.all_traits}"
|
62
|
-
)
|
63
|
-
sl = agent_list.select("persona").to_scenario_list()
|
64
|
-
sl.add_value("questions", [q.question_text for q in survey._questions])
|
65
|
-
results = q_eligibility.by(sl).by(model).run(cache=cache)
|
66
|
-
return [r == "Yes" for r in results.select("eligibility").to_list()]
|
67
|
-
|
68
|
-
|
69
|
-
def agent_eligibility(
|
70
|
-
agent: Agent,
|
71
|
-
survey: Survey,
|
72
|
-
model: Optional[Model] = None,
|
73
|
-
cache: Optional[Cache] = None,
|
74
|
-
) -> bool:
|
75
|
-
"""NB: This could be parallelized.
|
76
|
-
|
77
|
-
>>> from edsl.language_models import LanguageModel
|
78
|
-
>>> m = LanguageModel.example(canned_response = "1", test_model = True)
|
79
|
-
>>> agent_eligibility(agent = Agent.example().add_trait({'persona': "Persona"}), survey = Survey.example(), model = m)
|
80
|
-
True
|
81
|
-
|
82
|
-
"""
|
83
|
-
model = model or Model()
|
84
|
-
|
85
|
-
questions = [q.question_text for q in survey._questions]
|
86
|
-
persona = agent.traits["persona"]
|
87
|
-
return (
|
88
|
-
q_eligibility(model=model, questions=questions, persona=persona, cache=cache)
|
89
|
-
== "Yes"
|
90
|
-
)
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
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
|
-
|
215
|
-
#
|
216
|
-
#
|
217
|
-
#
|
218
|
-
#
|
219
|
-
# model=m,
|
220
|
-
# )
|
221
|
-
# example = [next(ag).select("new_agent_persona").first() for _ in range(10)]
|
222
|
-
# dimension_dict = {"attitude": ["positive", "negative"]}
|
223
|
-
# ag = gen_agent_traits(dimension_dict)
|
224
|
-
# example = [next(ag) for _ in range(100)]
|
1
|
+
from textwrap import dedent
|
2
|
+
import random
|
3
|
+
from typing import List, TypeVar, Generator, Optional
|
4
|
+
from edsl.auto.StageBase import StageBase
|
5
|
+
from edsl.utilities.naming_utilities import sanitize_string
|
6
|
+
from edsl import Agent, Survey, Model, Cache, AgentList
|
7
|
+
from edsl import QuestionFreeText, Scenario
|
8
|
+
from edsl import QuestionMultipleChoice, Scenario, Agent, ScenarioList
|
9
|
+
|
10
|
+
StageClassType = TypeVar("StageClassType", bound=StageBase)
|
11
|
+
|
12
|
+
|
13
|
+
def gen_pipeline(stages_list: List[StageClassType]) -> StageBase:
|
14
|
+
"""Takes as input a list of Stage classes & returns a pipeline of instantiated stages.
|
15
|
+
A pipeline is a linked list of stages where each stage has a next_stage attribute.
|
16
|
+
|
17
|
+
"""
|
18
|
+
pipeline = stages_list[0]()
|
19
|
+
last_stage = pipeline
|
20
|
+
for stage in stages_list[1:]:
|
21
|
+
while last_stage.next_stage is not None: # find the end of the pipeline
|
22
|
+
last_stage = last_stage.next_stage
|
23
|
+
stage_to_add = stage()
|
24
|
+
last_stage.next_stage = stage_to_add
|
25
|
+
return pipeline
|
26
|
+
|
27
|
+
|
28
|
+
q_eligibility = QuestionMultipleChoice(
|
29
|
+
question_text=dedent(
|
30
|
+
"""\
|
31
|
+
Consider this set of question: '{{ questions }}'.
|
32
|
+
Consider this persona: '{{ persona }}'.
|
33
|
+
Would this persona be able to answer all of these questions?
|
34
|
+
"""
|
35
|
+
),
|
36
|
+
question_options=["No", "Yes"],
|
37
|
+
question_name="eligibility",
|
38
|
+
)
|
39
|
+
|
40
|
+
|
41
|
+
def agent_list_eligibility(
|
42
|
+
agent_list: AgentList,
|
43
|
+
survey: Optional[Survey] = None,
|
44
|
+
model: Optional[Model] = None,
|
45
|
+
cache: Optional[Cache] = None,
|
46
|
+
) -> List[bool]:
|
47
|
+
"""
|
48
|
+
Returns whether each agent in a list is elgible for a survey i.e., can answer every question.
|
49
|
+
|
50
|
+
>>> from edsl.language_models import LanguageModel
|
51
|
+
>>> m = LanguageModel.example(canned_response = "1", test_model = True)
|
52
|
+
>>> agent_list_eligibility(AgentList.example())
|
53
|
+
[True, True]
|
54
|
+
>>> agent_list_eligibility(AgentList.example().add_trait('persona', 2*["Cool dude"]), survey = Survey.example(), model = m)
|
55
|
+
[True, True]
|
56
|
+
"""
|
57
|
+
if survey is None:
|
58
|
+
return [True] * len(agent_list)
|
59
|
+
if "persona" not in agent_list.all_traits:
|
60
|
+
raise ValueError(
|
61
|
+
f"Each agent needs to have a persona attribute; traits are {agent_list.all_traits}"
|
62
|
+
)
|
63
|
+
sl = agent_list.select("persona").to_scenario_list()
|
64
|
+
sl.add_value("questions", [q.question_text for q in survey._questions])
|
65
|
+
results = q_eligibility.by(sl).by(model).run(cache=cache)
|
66
|
+
return [r == "Yes" for r in results.select("eligibility").to_list()]
|
67
|
+
|
68
|
+
|
69
|
+
def agent_eligibility(
|
70
|
+
agent: Agent,
|
71
|
+
survey: Survey,
|
72
|
+
model: Optional[Model] = None,
|
73
|
+
cache: Optional[Cache] = None,
|
74
|
+
) -> bool:
|
75
|
+
"""NB: This could be parallelized.
|
76
|
+
|
77
|
+
>>> from edsl.language_models import LanguageModel
|
78
|
+
>>> m = LanguageModel.example(canned_response = "1", test_model = True)
|
79
|
+
>>> agent_eligibility(agent = Agent.example().add_trait({'persona': "Persona"}), survey = Survey.example(), model = m)
|
80
|
+
True
|
81
|
+
|
82
|
+
"""
|
83
|
+
model = model or Model()
|
84
|
+
|
85
|
+
questions = [q.question_text for q in survey._questions]
|
86
|
+
persona = agent.traits["persona"]
|
87
|
+
return (
|
88
|
+
q_eligibility(model=model, questions=questions, persona=persona, cache=cache)
|
89
|
+
== "Yes"
|
90
|
+
)
|
91
|
+
|
92
|
+
|
93
|
+
def gen_agent_traits(dimension_dict: dict, seed_value: Optional[str] = None):
|
94
|
+
"""
|
95
|
+
>>> dimension_dict = {'attitude':['positive', 'negative']}
|
96
|
+
>>> ag = gen_agent_traits(dimension_dict)
|
97
|
+
>>> a = next(ag)
|
98
|
+
>>> a == {'attitude': 'positive'} or a == {'attitude': 'negative'}
|
99
|
+
True
|
100
|
+
>>> len([next(ag) for _ in range(100)])
|
101
|
+
100
|
102
|
+
"""
|
103
|
+
if seed_value is None:
|
104
|
+
seed_value = "edsl"
|
105
|
+
|
106
|
+
random.seed(seed_value)
|
107
|
+
|
108
|
+
while True:
|
109
|
+
new_agent_traits = {}
|
110
|
+
for key, list_of_values in dimension_dict.items():
|
111
|
+
new_agent_traits[key] = random.choice(list_of_values)
|
112
|
+
yield new_agent_traits
|
113
|
+
|
114
|
+
|
115
|
+
def agent_generator(
|
116
|
+
persona: str,
|
117
|
+
dimension_dict: dict,
|
118
|
+
model: Optional[Model] = None,
|
119
|
+
cache: Optional["Cache"] = None,
|
120
|
+
) -> Generator["Results", None, None]:
|
121
|
+
"""
|
122
|
+
>>> from edsl.language_models import LanguageModel
|
123
|
+
>>> m = LanguageModel.example(canned_response = "This is a cool dude.", test_model = True)
|
124
|
+
>>> ag = agent_generator(persona = "Base person", dimension_dict = {'attitude':['Positive', 'Negative']}, model = m)
|
125
|
+
>>> next(ag).select('new_agent_persona').first()
|
126
|
+
'This is a cool dude.'
|
127
|
+
>>> next(ag).select('new_agent_persona').first()
|
128
|
+
'This is a cool dude.'
|
129
|
+
"""
|
130
|
+
|
131
|
+
if model is None:
|
132
|
+
model = Model()
|
133
|
+
|
134
|
+
q = QuestionFreeText(
|
135
|
+
question_text=dedent(
|
136
|
+
"""\
|
137
|
+
Consider this persona: '{{ persona }}'.
|
138
|
+
Now imagine writing a new persona with these traits:
|
139
|
+
'{{ new_agent_traits }}'
|
140
|
+
Please write this persona as a narrative.
|
141
|
+
"""
|
142
|
+
),
|
143
|
+
question_name="new_agent_persona",
|
144
|
+
)
|
145
|
+
agent_trait_generator = gen_agent_traits(dimension_dict)
|
146
|
+
codebook = {sanitize_string(k): k for k in dimension_dict.keys()}
|
147
|
+
while True:
|
148
|
+
new_agent_traits = next(agent_trait_generator)
|
149
|
+
yield q(
|
150
|
+
persona=persona,
|
151
|
+
new_agent_traits=new_agent_traits,
|
152
|
+
codebook=codebook,
|
153
|
+
just_answer=False,
|
154
|
+
cache=cache,
|
155
|
+
model=model,
|
156
|
+
)
|
157
|
+
|
158
|
+
|
159
|
+
def create_agents(
|
160
|
+
agent_generator: Generator["Results", None, None],
|
161
|
+
survey: Optional[Survey] = None,
|
162
|
+
num_agents=11,
|
163
|
+
) -> AgentList:
|
164
|
+
"""
|
165
|
+
>>> from edsl.language_models import LanguageModel
|
166
|
+
>>> m = LanguageModel.example(canned_response = "This is a cool dude.", test_model = True)
|
167
|
+
>>> ag = agent_generator(persona = "Base person", dimension_dict = {'attitude':['Positive', 'Negative']}, model = m)
|
168
|
+
>>> new_agent_list = create_agents(agent_generator = ag)
|
169
|
+
>>> new_agent_list
|
170
|
+
|
171
|
+
"""
|
172
|
+
agent_list = AgentList([])
|
173
|
+
|
174
|
+
MAX_ITERATIONS_MULTIPLIER = 2
|
175
|
+
iterations = 0
|
176
|
+
|
177
|
+
while len(agent_list) < num_agents:
|
178
|
+
iterations += 1
|
179
|
+
candidate_agent = next(agent_generator)
|
180
|
+
codebook = candidate_agent.select("codebook").to_list()[0]
|
181
|
+
|
182
|
+
koobedoc = {v: k for k, v in codebook.items()}
|
183
|
+
persona = candidate_agent.select("new_agent_persona").to_list()[0]
|
184
|
+
traits = candidate_agent.select("new_agent_traits").to_list()[0]
|
185
|
+
new_traits = {koobedoc[key]: value for key, value in traits.items()} | {
|
186
|
+
"persona": persona
|
187
|
+
}
|
188
|
+
agent = Agent(traits=new_traits, codebook=codebook)
|
189
|
+
if survey is not None:
|
190
|
+
if agent_eligibility(agent, survey):
|
191
|
+
agent_list.append(agent)
|
192
|
+
else:
|
193
|
+
print("Agent not eligible")
|
194
|
+
else:
|
195
|
+
agent_list.append(agent)
|
196
|
+
|
197
|
+
if iterations > MAX_ITERATIONS_MULTIPLIER * num_agents:
|
198
|
+
raise Exception("Too many failures")
|
199
|
+
|
200
|
+
return agent_list
|
201
|
+
|
202
|
+
|
203
|
+
if __name__ == "__main__":
|
204
|
+
import doctest
|
205
|
+
|
206
|
+
doctest.testmod()
|
207
|
+
# from edsl.language_models import LanguageModel
|
208
|
+
|
209
|
+
# m = LanguageModel.example(canned_response="This is a cool dude.", test_model=True)
|
210
|
+
# ag = agent_generator(
|
211
|
+
# persona="Base person",
|
212
|
+
# dimension_dict={"attitude": ["Positive", "Negative"]},
|
213
|
+
# model=m,
|
214
|
+
# )
|
215
|
+
# example = [next(ag).select("new_agent_persona").first() for _ in range(10)]
|
216
|
+
# dimension_dict = {"attitude": ["positive", "negative"]}
|
217
|
+
# ag = gen_agent_traits(dimension_dict)
|
218
|
+
# example = [next(ag) for _ in range(100)]
|