edsl 0.1.32__py3-none-any.whl → 0.1.33__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 +9 -3
- edsl/TemplateLoader.py +24 -0
- edsl/__init__.py +8 -3
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +40 -8
- edsl/agents/AgentList.py +43 -0
- edsl/agents/Invigilator.py +135 -219
- edsl/agents/InvigilatorBase.py +148 -59
- edsl/agents/{PromptConstructionMixin.py → PromptConstructor.py} +138 -89
- edsl/agents/__init__.py +1 -0
- edsl/auto/AutoStudy.py +117 -0
- edsl/auto/StageBase.py +230 -0
- edsl/auto/StageGenerateSurvey.py +178 -0
- edsl/auto/StageLabelQuestions.py +125 -0
- edsl/auto/StagePersona.py +61 -0
- edsl/auto/StagePersonaDimensionValueRanges.py +88 -0
- edsl/auto/StagePersonaDimensionValues.py +74 -0
- edsl/auto/StagePersonaDimensions.py +69 -0
- edsl/auto/StageQuestions.py +73 -0
- edsl/auto/SurveyCreatorPipeline.py +21 -0
- edsl/auto/utilities.py +224 -0
- edsl/config.py +47 -56
- edsl/coop/PriceFetcher.py +58 -0
- edsl/coop/coop.py +50 -7
- edsl/data/Cache.py +35 -1
- edsl/data_transfer_models.py +73 -38
- edsl/enums.py +4 -0
- edsl/exceptions/language_models.py +25 -1
- edsl/exceptions/questions.py +62 -5
- edsl/exceptions/results.py +4 -0
- edsl/inference_services/AnthropicService.py +13 -11
- edsl/inference_services/AwsBedrock.py +19 -17
- edsl/inference_services/AzureAI.py +37 -20
- edsl/inference_services/GoogleService.py +16 -12
- edsl/inference_services/GroqService.py +2 -0
- edsl/inference_services/InferenceServiceABC.py +58 -3
- edsl/inference_services/MistralAIService.py +120 -0
- edsl/inference_services/OpenAIService.py +48 -54
- edsl/inference_services/TestService.py +80 -0
- edsl/inference_services/TogetherAIService.py +170 -0
- edsl/inference_services/models_available_cache.py +0 -6
- edsl/inference_services/registry.py +6 -0
- edsl/jobs/Answers.py +10 -12
- edsl/jobs/FailedQuestion.py +78 -0
- edsl/jobs/Jobs.py +37 -22
- edsl/jobs/buckets/BucketCollection.py +24 -15
- edsl/jobs/buckets/TokenBucket.py +93 -14
- edsl/jobs/interviews/Interview.py +366 -78
- edsl/jobs/interviews/{interview_exception_tracking.py → InterviewExceptionCollection.py} +14 -68
- edsl/jobs/interviews/InterviewExceptionEntry.py +85 -19
- edsl/jobs/runners/JobsRunnerAsyncio.py +146 -175
- edsl/jobs/runners/JobsRunnerStatus.py +331 -0
- edsl/jobs/tasks/QuestionTaskCreator.py +30 -23
- edsl/jobs/tasks/TaskHistory.py +148 -213
- edsl/language_models/LanguageModel.py +261 -156
- edsl/language_models/ModelList.py +2 -2
- edsl/language_models/RegisterLanguageModelsMeta.py +14 -29
- edsl/language_models/fake_openai_call.py +15 -0
- edsl/language_models/fake_openai_service.py +61 -0
- edsl/language_models/registry.py +23 -6
- edsl/language_models/repair.py +0 -19
- edsl/language_models/utilities.py +61 -0
- edsl/notebooks/Notebook.py +20 -2
- edsl/prompts/Prompt.py +52 -2
- edsl/questions/AnswerValidatorMixin.py +23 -26
- edsl/questions/QuestionBase.py +330 -249
- edsl/questions/QuestionBaseGenMixin.py +133 -0
- edsl/questions/QuestionBasePromptsMixin.py +266 -0
- edsl/questions/QuestionBudget.py +99 -41
- edsl/questions/QuestionCheckBox.py +227 -35
- edsl/questions/QuestionExtract.py +98 -27
- edsl/questions/QuestionFreeText.py +52 -29
- edsl/questions/QuestionFunctional.py +7 -0
- edsl/questions/QuestionList.py +141 -22
- edsl/questions/QuestionMultipleChoice.py +159 -65
- edsl/questions/QuestionNumerical.py +88 -46
- edsl/questions/QuestionRank.py +182 -24
- edsl/questions/Quick.py +41 -0
- edsl/questions/RegisterQuestionsMeta.py +31 -12
- edsl/questions/ResponseValidatorABC.py +170 -0
- edsl/questions/__init__.py +3 -4
- edsl/questions/decorators.py +21 -0
- edsl/questions/derived/QuestionLikertFive.py +10 -5
- edsl/questions/derived/QuestionLinearScale.py +15 -2
- edsl/questions/derived/QuestionTopK.py +10 -1
- edsl/questions/derived/QuestionYesNo.py +24 -3
- edsl/questions/descriptors.py +43 -7
- edsl/questions/prompt_templates/question_budget.jinja +13 -0
- edsl/questions/prompt_templates/question_checkbox.jinja +32 -0
- edsl/questions/prompt_templates/question_extract.jinja +11 -0
- edsl/questions/prompt_templates/question_free_text.jinja +3 -0
- edsl/questions/prompt_templates/question_linear_scale.jinja +11 -0
- edsl/questions/prompt_templates/question_list.jinja +17 -0
- edsl/questions/prompt_templates/question_multiple_choice.jinja +33 -0
- edsl/questions/prompt_templates/question_numerical.jinja +37 -0
- edsl/questions/question_registry.py +6 -2
- edsl/questions/templates/__init__.py +0 -0
- edsl/questions/templates/budget/__init__.py +0 -0
- edsl/questions/templates/budget/answering_instructions.jinja +7 -0
- edsl/questions/templates/budget/question_presentation.jinja +7 -0
- edsl/questions/templates/checkbox/__init__.py +0 -0
- edsl/questions/templates/checkbox/answering_instructions.jinja +10 -0
- edsl/questions/templates/checkbox/question_presentation.jinja +22 -0
- edsl/questions/templates/extract/__init__.py +0 -0
- edsl/questions/templates/extract/answering_instructions.jinja +7 -0
- edsl/questions/templates/extract/question_presentation.jinja +1 -0
- edsl/questions/templates/free_text/__init__.py +0 -0
- edsl/questions/templates/free_text/answering_instructions.jinja +0 -0
- edsl/questions/templates/free_text/question_presentation.jinja +1 -0
- edsl/questions/templates/likert_five/__init__.py +0 -0
- edsl/questions/templates/likert_five/answering_instructions.jinja +10 -0
- edsl/questions/templates/likert_five/question_presentation.jinja +12 -0
- edsl/questions/templates/linear_scale/__init__.py +0 -0
- edsl/questions/templates/linear_scale/answering_instructions.jinja +5 -0
- edsl/questions/templates/linear_scale/question_presentation.jinja +5 -0
- edsl/questions/templates/list/__init__.py +0 -0
- edsl/questions/templates/list/answering_instructions.jinja +4 -0
- edsl/questions/templates/list/question_presentation.jinja +5 -0
- edsl/questions/templates/multiple_choice/__init__.py +0 -0
- edsl/questions/templates/multiple_choice/answering_instructions.jinja +9 -0
- edsl/questions/templates/multiple_choice/html.jinja +0 -0
- edsl/questions/templates/multiple_choice/question_presentation.jinja +12 -0
- edsl/questions/templates/numerical/__init__.py +0 -0
- edsl/questions/templates/numerical/answering_instructions.jinja +8 -0
- edsl/questions/templates/numerical/question_presentation.jinja +7 -0
- edsl/questions/templates/rank/__init__.py +0 -0
- edsl/questions/templates/rank/answering_instructions.jinja +11 -0
- edsl/questions/templates/rank/question_presentation.jinja +15 -0
- edsl/questions/templates/top_k/__init__.py +0 -0
- edsl/questions/templates/top_k/answering_instructions.jinja +8 -0
- edsl/questions/templates/top_k/question_presentation.jinja +22 -0
- edsl/questions/templates/yes_no/__init__.py +0 -0
- edsl/questions/templates/yes_no/answering_instructions.jinja +6 -0
- edsl/questions/templates/yes_no/question_presentation.jinja +12 -0
- edsl/results/Dataset.py +20 -0
- edsl/results/DatasetExportMixin.py +46 -48
- edsl/results/DatasetTree.py +145 -0
- edsl/results/Result.py +32 -5
- edsl/results/Results.py +135 -46
- edsl/results/ResultsDBMixin.py +3 -3
- edsl/results/Selector.py +118 -0
- edsl/results/tree_explore.py +115 -0
- edsl/scenarios/FileStore.py +71 -10
- edsl/scenarios/Scenario.py +96 -25
- edsl/scenarios/ScenarioImageMixin.py +2 -2
- edsl/scenarios/ScenarioList.py +361 -39
- edsl/scenarios/ScenarioListExportMixin.py +9 -0
- edsl/scenarios/ScenarioListPdfMixin.py +150 -4
- edsl/study/SnapShot.py +8 -1
- edsl/study/Study.py +32 -0
- edsl/surveys/Rule.py +10 -1
- edsl/surveys/RuleCollection.py +21 -5
- edsl/surveys/Survey.py +637 -311
- edsl/surveys/SurveyExportMixin.py +71 -9
- edsl/surveys/SurveyFlowVisualizationMixin.py +2 -1
- edsl/surveys/SurveyQualtricsImport.py +75 -4
- edsl/surveys/instructions/ChangeInstruction.py +47 -0
- edsl/surveys/instructions/Instruction.py +34 -0
- edsl/surveys/instructions/InstructionCollection.py +77 -0
- edsl/surveys/instructions/__init__.py +0 -0
- edsl/templates/error_reporting/base.html +24 -0
- edsl/templates/error_reporting/exceptions_by_model.html +35 -0
- edsl/templates/error_reporting/exceptions_by_question_name.html +17 -0
- edsl/templates/error_reporting/exceptions_by_type.html +17 -0
- edsl/templates/error_reporting/interview_details.html +116 -0
- edsl/templates/error_reporting/interviews.html +10 -0
- edsl/templates/error_reporting/overview.html +5 -0
- edsl/templates/error_reporting/performance_plot.html +2 -0
- edsl/templates/error_reporting/report.css +74 -0
- edsl/templates/error_reporting/report.html +118 -0
- edsl/templates/error_reporting/report.js +25 -0
- edsl/utilities/utilities.py +9 -1
- {edsl-0.1.32.dist-info → edsl-0.1.33.dist-info}/METADATA +5 -2
- edsl-0.1.33.dist-info/RECORD +295 -0
- edsl/jobs/interviews/InterviewTaskBuildingMixin.py +0 -286
- edsl/jobs/interviews/retry_management.py +0 -37
- edsl/jobs/runners/JobsRunnerStatusMixin.py +0 -333
- edsl/utilities/gcp_bucket/simple_example.py +0 -9
- edsl-0.1.32.dist-info/RECORD +0 -209
- {edsl-0.1.32.dist-info → edsl-0.1.33.dist-info}/LICENSE +0 -0
- {edsl-0.1.32.dist-info → edsl-0.1.33.dist-info}/WHEEL +0 -0
edsl/study/Study.py
CHANGED
@@ -469,6 +469,38 @@ class Study:
|
|
469
469
|
coop = Coop()
|
470
470
|
return coop.create(self, description=self.description)
|
471
471
|
|
472
|
+
def delete_object(self, identifier: Union[str, UUID]):
|
473
|
+
"""
|
474
|
+
Delete an EDSL object from the study.
|
475
|
+
|
476
|
+
:param identifier: Either the variable name or the hash of the object to delete
|
477
|
+
:raises ValueError: If the object is not found in the study
|
478
|
+
"""
|
479
|
+
if isinstance(identifier, str):
|
480
|
+
# If identifier is a variable name or a string representation of UUID
|
481
|
+
for hash, obj_entry in list(self.objects.items()):
|
482
|
+
if obj_entry.variable_name == identifier or hash == identifier:
|
483
|
+
del self.objects[hash]
|
484
|
+
self._create_mapping_dicts() # Update internal mappings
|
485
|
+
if self.verbose:
|
486
|
+
print(f"Deleted object with identifier: {identifier}")
|
487
|
+
return
|
488
|
+
raise ValueError(f"No object found with identifier: {identifier}")
|
489
|
+
elif isinstance(identifier, UUID):
|
490
|
+
# If identifier is a UUID object
|
491
|
+
hash_str = str(identifier)
|
492
|
+
if hash_str in self.objects:
|
493
|
+
del self.objects[hash_str]
|
494
|
+
self._create_mapping_dicts() # Update internal mappings
|
495
|
+
if self.verbose:
|
496
|
+
print(f"Deleted object with hash: {hash_str}")
|
497
|
+
return
|
498
|
+
raise ValueError(f"No object found with hash: {hash_str}")
|
499
|
+
else:
|
500
|
+
raise TypeError(
|
501
|
+
"Identifier must be either a string (variable name or hash) or a UUID object"
|
502
|
+
)
|
503
|
+
|
472
504
|
@classmethod
|
473
505
|
def pull(cls, uuid: Optional[Union[str, UUID]] = None, url: Optional[str] = None):
|
474
506
|
"""Pull the object from coop."""
|
edsl/surveys/Rule.py
CHANGED
@@ -18,6 +18,7 @@ with a low (-1) priority.
|
|
18
18
|
"""
|
19
19
|
|
20
20
|
import ast
|
21
|
+
import random
|
21
22
|
from typing import Any, Union, List
|
22
23
|
|
23
24
|
from jinja2 import Template
|
@@ -254,8 +255,16 @@ class Rule:
|
|
254
255
|
msg = f"""Exception in evaluation: {e}. The expression is: {self.expression}. The current info env trying to substitute in is: {current_info_env}. After the substition, the expression was: {to_evaluate}."""
|
255
256
|
raise SurveyRuleCannotEvaluateError(msg)
|
256
257
|
|
258
|
+
random_functions = {
|
259
|
+
"randint": random.randint,
|
260
|
+
"choice": random.choice,
|
261
|
+
"random": random.random,
|
262
|
+
"uniform": random.uniform,
|
263
|
+
# Add any other random functions you want to allow
|
264
|
+
}
|
265
|
+
|
257
266
|
try:
|
258
|
-
return EvalWithCompoundTypes().eval(to_evaluate)
|
267
|
+
return EvalWithCompoundTypes(functions=random_functions).eval(to_evaluate)
|
259
268
|
except Exception as e:
|
260
269
|
msg = f"""Exception in evaluation: {e}. The expression is: {self.expression}. The current info env trying to substitute in is: {current_info_env}. After the substition, the expression was: {to_evaluate}."""
|
261
270
|
raise SurveyRuleCannotEvaluateError(msg)
|
edsl/surveys/RuleCollection.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"""A collection of rules for a survey."""
|
2
2
|
|
3
|
-
from typing import List, Union, Any
|
3
|
+
from typing import List, Union, Any, Optional
|
4
4
|
from collections import defaultdict, UserList
|
5
5
|
|
6
6
|
from edsl.exceptions import (
|
@@ -24,7 +24,7 @@ NextQuestion = namedtuple(
|
|
24
24
|
class RuleCollection(UserList):
|
25
25
|
"""A collection of rules for a particular survey."""
|
26
26
|
|
27
|
-
def __init__(self, num_questions: int = None, rules: List[Rule] = None):
|
27
|
+
def __init__(self, num_questions: Optional[int] = None, rules: List[Rule] = None):
|
28
28
|
"""Initialize the RuleCollection object.
|
29
29
|
|
30
30
|
:param num_questions: The number of questions in the survey.
|
@@ -172,7 +172,8 @@ class RuleCollection(UserList):
|
|
172
172
|
|
173
173
|
def next_question(self, q_now: int, answers: dict[str, Any]) -> NextQuestion:
|
174
174
|
"""Find the next question by index, given the rule collection.
|
175
|
-
|
175
|
+
|
176
|
+
This rule is applied after the question is answered.
|
176
177
|
|
177
178
|
:param q_now: The current question index.
|
178
179
|
:param answers: The answers to the survey questions so far, including the current question.
|
@@ -182,8 +183,17 @@ class RuleCollection(UserList):
|
|
182
183
|
NextQuestion(next_q=3, num_rules_found=2, expressions_evaluating_to_true=1, priority=1)
|
183
184
|
|
184
185
|
"""
|
185
|
-
#
|
186
|
-
|
186
|
+
# # is this the first question? If it is, we need to check if it should be skipped.
|
187
|
+
# if q_now == 0:
|
188
|
+
# if self.skip_question_before_running(q_now, answers):
|
189
|
+
# return NextQuestion(
|
190
|
+
# next_q=q_now + 1,
|
191
|
+
# num_rules_found=0,
|
192
|
+
# expressions_evaluating_to_true=0,
|
193
|
+
# priority=-1,
|
194
|
+
# )
|
195
|
+
|
196
|
+
# breakpoint()
|
187
197
|
expressions_evaluating_to_true = 0
|
188
198
|
next_q = None
|
189
199
|
highest_priority = -2 # start with -2 to 'pick up' the default rule added
|
@@ -205,6 +215,12 @@ class RuleCollection(UserList):
|
|
205
215
|
f"No rules found for question {q_now}"
|
206
216
|
)
|
207
217
|
|
218
|
+
# breakpoint()
|
219
|
+
## Now we need to check if the *next question* has any 'before; rules that we should follow
|
220
|
+
for rule in self.applicable_rules(next_q, before_rule=True):
|
221
|
+
if rule.evaluate(answers): # rule evaluates to True
|
222
|
+
return self.next_question(next_q, answers)
|
223
|
+
|
208
224
|
return NextQuestion(
|
209
225
|
next_q, num_rules_found, expressions_evaluating_to_true, highest_priority
|
210
226
|
)
|