edsl 0.1.38.dev4__py3-none-any.whl → 0.1.39__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 +197 -116
- edsl/__init__.py +15 -7
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +351 -147
- edsl/agents/AgentList.py +211 -73
- edsl/agents/Invigilator.py +101 -50
- edsl/agents/InvigilatorBase.py +62 -70
- edsl/agents/PromptConstructor.py +143 -225
- edsl/agents/QuestionInstructionPromptBuilder.py +128 -0
- edsl/agents/QuestionTemplateReplacementsBuilder.py +137 -0
- edsl/agents/__init__.py +0 -1
- edsl/agents/prompt_helpers.py +3 -3
- edsl/agents/question_option_processor.py +172 -0
- edsl/auto/AutoStudy.py +18 -5
- edsl/auto/StageBase.py +53 -40
- edsl/auto/StageQuestions.py +2 -1
- edsl/auto/utilities.py +0 -6
- edsl/config.py +22 -2
- edsl/conversation/car_buying.py +2 -1
- edsl/coop/CoopFunctionsMixin.py +15 -0
- edsl/coop/ExpectedParrotKeyHandler.py +125 -0
- edsl/coop/PriceFetcher.py +1 -1
- edsl/coop/coop.py +125 -47
- edsl/coop/utils.py +14 -14
- edsl/data/Cache.py +45 -27
- edsl/data/CacheEntry.py +12 -15
- edsl/data/CacheHandler.py +31 -12
- edsl/data/RemoteCacheSync.py +154 -46
- edsl/data/__init__.py +4 -3
- edsl/data_transfer_models.py +2 -1
- edsl/enums.py +27 -0
- edsl/exceptions/__init__.py +50 -50
- edsl/exceptions/agents.py +12 -0
- edsl/exceptions/inference_services.py +5 -0
- edsl/exceptions/questions.py +24 -6
- edsl/exceptions/scenarios.py +7 -0
- edsl/inference_services/AnthropicService.py +38 -19
- edsl/inference_services/AvailableModelCacheHandler.py +184 -0
- edsl/inference_services/AvailableModelFetcher.py +215 -0
- edsl/inference_services/AwsBedrock.py +0 -2
- edsl/inference_services/AzureAI.py +0 -2
- edsl/inference_services/GoogleService.py +7 -12
- edsl/inference_services/InferenceServiceABC.py +18 -85
- edsl/inference_services/InferenceServicesCollection.py +120 -79
- edsl/inference_services/MistralAIService.py +0 -3
- edsl/inference_services/OpenAIService.py +47 -35
- edsl/inference_services/PerplexityService.py +0 -3
- edsl/inference_services/ServiceAvailability.py +135 -0
- edsl/inference_services/TestService.py +11 -10
- edsl/inference_services/TogetherAIService.py +5 -3
- edsl/inference_services/data_structures.py +134 -0
- edsl/jobs/AnswerQuestionFunctionConstructor.py +223 -0
- edsl/jobs/Answers.py +1 -14
- edsl/jobs/FetchInvigilator.py +47 -0
- edsl/jobs/InterviewTaskManager.py +98 -0
- edsl/jobs/InterviewsConstructor.py +50 -0
- edsl/jobs/Jobs.py +356 -431
- edsl/jobs/JobsChecks.py +35 -10
- edsl/jobs/JobsComponentConstructor.py +189 -0
- edsl/jobs/JobsPrompts.py +6 -4
- edsl/jobs/JobsRemoteInferenceHandler.py +205 -133
- edsl/jobs/JobsRemoteInferenceLogger.py +239 -0
- edsl/jobs/RequestTokenEstimator.py +30 -0
- edsl/jobs/async_interview_runner.py +138 -0
- edsl/jobs/buckets/BucketCollection.py +44 -3
- edsl/jobs/buckets/TokenBucket.py +53 -21
- 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 +143 -408
- 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 +88 -403
- edsl/jobs/runners/JobsRunnerStatus.py +133 -165
- edsl/jobs/tasks/QuestionTaskCreator.py +21 -19
- edsl/jobs/tasks/TaskHistory.py +38 -18
- edsl/jobs/tasks/task_status_enum.py +0 -2
- edsl/language_models/ComputeCost.py +63 -0
- edsl/language_models/LanguageModel.py +194 -236
- edsl/language_models/ModelList.py +28 -19
- edsl/language_models/PriceManager.py +127 -0
- edsl/language_models/RawResponseHandler.py +106 -0
- edsl/language_models/ServiceDataSources.py +0 -0
- edsl/language_models/__init__.py +1 -2
- 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 +2 -2
- edsl/language_models/utilities.py +5 -4
- edsl/notebooks/Notebook.py +19 -14
- edsl/notebooks/NotebookToLaTeX.py +142 -0
- edsl/prompts/Prompt.py +29 -39
- edsl/questions/ExceptionExplainer.py +77 -0
- edsl/questions/HTMLQuestion.py +103 -0
- edsl/questions/QuestionBase.py +68 -214
- edsl/questions/QuestionBasePromptsMixin.py +7 -3
- edsl/questions/QuestionBudget.py +1 -1
- edsl/questions/QuestionCheckBox.py +3 -3
- edsl/questions/QuestionExtract.py +5 -7
- edsl/questions/QuestionFreeText.py +2 -3
- edsl/questions/QuestionList.py +10 -18
- edsl/questions/QuestionMatrix.py +265 -0
- edsl/questions/QuestionMultipleChoice.py +67 -23
- edsl/questions/QuestionNumerical.py +2 -4
- edsl/questions/QuestionRank.py +7 -17
- edsl/questions/SimpleAskMixin.py +4 -3
- edsl/questions/__init__.py +2 -1
- edsl/questions/{AnswerValidatorMixin.py → answer_validator_mixin.py} +47 -2
- edsl/questions/data_structures.py +20 -0
- edsl/questions/derived/QuestionLinearScale.py +6 -3
- edsl/questions/derived/QuestionTopK.py +1 -1
- edsl/questions/descriptors.py +17 -3
- edsl/questions/loop_processor.py +149 -0
- edsl/questions/{QuestionBaseGenMixin.py → question_base_gen_mixin.py} +57 -50
- edsl/questions/question_registry.py +1 -1
- edsl/questions/{ResponseValidatorABC.py → response_validator_abc.py} +40 -26
- edsl/questions/response_validator_factory.py +34 -0
- 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/results/CSSParameterizer.py +1 -1
- edsl/results/Dataset.py +170 -7
- edsl/results/DatasetExportMixin.py +168 -305
- edsl/results/DatasetTree.py +28 -8
- edsl/results/MarkdownToDocx.py +122 -0
- edsl/results/MarkdownToPDF.py +111 -0
- edsl/results/Result.py +298 -206
- edsl/results/Results.py +149 -131
- edsl/results/ResultsExportMixin.py +2 -0
- edsl/results/TableDisplay.py +98 -171
- edsl/results/TextEditor.py +50 -0
- edsl/results/__init__.py +1 -1
- edsl/results/file_exports.py +252 -0
- edsl/results/{Selector.py → results_selector.py} +23 -13
- edsl/results/smart_objects.py +96 -0
- edsl/results/table_data_class.py +12 -0
- edsl/results/table_renderers.py +118 -0
- edsl/scenarios/ConstructDownloadLink.py +109 -0
- edsl/scenarios/DocumentChunker.py +102 -0
- edsl/scenarios/DocxScenario.py +16 -0
- edsl/scenarios/FileStore.py +150 -239
- edsl/scenarios/PdfExtractor.py +40 -0
- edsl/scenarios/Scenario.py +90 -193
- edsl/scenarios/ScenarioHtmlMixin.py +4 -3
- edsl/scenarios/ScenarioList.py +415 -244
- edsl/scenarios/ScenarioListExportMixin.py +0 -7
- edsl/scenarios/ScenarioListPdfMixin.py +15 -37
- edsl/scenarios/__init__.py +1 -2
- 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 +49 -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} +10 -6
- edsl/scenarios/scenario_selector.py +156 -0
- edsl/study/ObjectEntry.py +1 -1
- edsl/study/SnapShot.py +1 -1
- edsl/study/Study.py +5 -12
- edsl/surveys/ConstructDAG.py +92 -0
- edsl/surveys/EditSurvey.py +221 -0
- edsl/surveys/InstructionHandler.py +100 -0
- edsl/surveys/MemoryManagement.py +72 -0
- edsl/surveys/Rule.py +5 -4
- edsl/surveys/RuleCollection.py +25 -27
- edsl/surveys/RuleManager.py +172 -0
- edsl/surveys/Simulator.py +75 -0
- edsl/surveys/Survey.py +270 -791
- edsl/surveys/SurveyCSS.py +20 -8
- edsl/surveys/{SurveyFlowVisualizationMixin.py → SurveyFlowVisualization.py} +11 -9
- edsl/surveys/SurveyToApp.py +141 -0
- edsl/surveys/__init__.py +4 -2
- edsl/surveys/descriptors.py +6 -2
- edsl/surveys/instructions/ChangeInstruction.py +1 -2
- edsl/surveys/instructions/Instruction.py +4 -13
- edsl/surveys/instructions/InstructionCollection.py +11 -6
- edsl/templates/error_reporting/interview_details.html +1 -1
- edsl/templates/error_reporting/report.html +1 -1
- edsl/tools/plotting.py +1 -1
- edsl/utilities/PrettyList.py +56 -0
- edsl/utilities/is_notebook.py +18 -0
- edsl/utilities/is_valid_variable_name.py +11 -0
- edsl/utilities/remove_edsl_version.py +24 -0
- edsl/utilities/utilities.py +35 -23
- {edsl-0.1.38.dev4.dist-info → edsl-0.1.39.dist-info}/METADATA +12 -10
- edsl-0.1.39.dist-info/RECORD +358 -0
- {edsl-0.1.38.dev4.dist-info → edsl-0.1.39.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.38.dev4.dist-info/RECORD +0 -277
- /edsl/questions/{RegisterQuestionsMeta.py → register_questions_meta.py} +0 -0
- /edsl/results/{ResultsFetchMixin.py → results_fetch_mixin.py} +0 -0
- /edsl/results/{ResultsToolsMixin.py → results_tools_mixin.py} +0 -0
- {edsl-0.1.38.dev4.dist-info → edsl-0.1.39.dist-info}/LICENSE +0 -0
edsl/jobs/JobsChecks.py
CHANGED
@@ -1,16 +1,21 @@
|
|
1
1
|
import os
|
2
|
-
from edsl.exceptions import MissingAPIKeyError
|
2
|
+
from edsl.exceptions.general import MissingAPIKeyError
|
3
3
|
|
4
4
|
|
5
5
|
class JobsChecks:
|
6
6
|
def __init__(self, jobs):
|
7
|
-
""" """
|
7
|
+
"""Checks a Jobs object for missing API keys and other requirements."""
|
8
8
|
self.jobs = jobs
|
9
9
|
|
10
10
|
def check_api_keys(self) -> None:
|
11
|
-
from edsl import Model
|
11
|
+
from edsl.language_models.model import Model
|
12
12
|
|
13
|
-
|
13
|
+
if len(self.jobs.models) == 0:
|
14
|
+
models = [Model()]
|
15
|
+
else:
|
16
|
+
models = self.jobs.models
|
17
|
+
|
18
|
+
for model in models: # + [Model()]:
|
14
19
|
if not model.has_valid_api_key():
|
15
20
|
raise MissingAPIKeyError(
|
16
21
|
model_name=str(model.model),
|
@@ -23,7 +28,7 @@ class JobsChecks:
|
|
23
28
|
"""
|
24
29
|
missing_api_keys = set()
|
25
30
|
|
26
|
-
from edsl import Model
|
31
|
+
from edsl.language_models.model import Model
|
27
32
|
from edsl.enums import service_to_api_keyname
|
28
33
|
|
29
34
|
for model in self.jobs.models + [Model()]:
|
@@ -95,16 +100,33 @@ class JobsChecks:
|
|
95
100
|
return True
|
96
101
|
|
97
102
|
def needs_key_process(self):
|
103
|
+
"""
|
104
|
+
A User needs the key process when:
|
105
|
+
1. They don't have all the model keys
|
106
|
+
2. They don't have the EP API
|
107
|
+
3. They need external LLMs to run the job
|
108
|
+
"""
|
98
109
|
return (
|
99
110
|
not self.user_has_all_model_keys()
|
100
111
|
and not self.user_has_ep_api_key()
|
101
112
|
and self.needs_external_llms()
|
102
113
|
)
|
103
114
|
|
115
|
+
def status(self) -> dict:
|
116
|
+
"""
|
117
|
+
Returns a dictionary with the status of the job checks.
|
118
|
+
"""
|
119
|
+
return {
|
120
|
+
"user_has_ep_api_key": self.user_has_ep_api_key(),
|
121
|
+
"user_has_all_model_keys": self.user_has_all_model_keys(),
|
122
|
+
"needs_external_llms": self.needs_external_llms(),
|
123
|
+
"needs_key_process": self.needs_key_process(),
|
124
|
+
}
|
125
|
+
|
104
126
|
def key_process(self):
|
105
127
|
import secrets
|
106
128
|
from dotenv import load_dotenv
|
107
|
-
from edsl import CONFIG
|
129
|
+
from edsl.config import CONFIG
|
108
130
|
from edsl.coop.coop import Coop
|
109
131
|
from edsl.utilities.utilities import write_api_key_to_env
|
110
132
|
|
@@ -119,10 +141,12 @@ class JobsChecks:
|
|
119
141
|
"\nYou can either add the missing keys to your .env file, or use remote inference."
|
120
142
|
)
|
121
143
|
print("Remote inference allows you to run jobs on our server.")
|
122
|
-
print("\n🚀 To use remote inference, sign up at the following link:")
|
123
144
|
|
124
145
|
coop = Coop()
|
125
|
-
coop._display_login_url(
|
146
|
+
coop._display_login_url(
|
147
|
+
edsl_auth_token=edsl_auth_token,
|
148
|
+
link_description="\n🚀 To use remote inference, sign up at the following link:",
|
149
|
+
)
|
126
150
|
|
127
151
|
print(
|
128
152
|
"\nOnce you log in, we will automatically retrieve your Expected Parrot API key and continue your job remotely."
|
@@ -134,8 +158,9 @@ class JobsChecks:
|
|
134
158
|
print("\nTimed out waiting for login. Please try again.")
|
135
159
|
return
|
136
160
|
|
137
|
-
write_api_key_to_env(api_key)
|
138
|
-
print("✨ API key retrieved and written to .env file
|
161
|
+
path_to_env = write_api_key_to_env(api_key)
|
162
|
+
print("\n✨ API key retrieved and written to .env file at the following path:")
|
163
|
+
print(f" {path_to_env}")
|
139
164
|
|
140
165
|
# Retrieve API key so we can continue running the job
|
141
166
|
load_dotenv()
|
@@ -0,0 +1,189 @@
|
|
1
|
+
from typing import Union, Sequence, TYPE_CHECKING
|
2
|
+
|
3
|
+
if TYPE_CHECKING:
|
4
|
+
from edsl.agents.Agent import Agent
|
5
|
+
from edsl.language_models.LanguageModel import LanguageModel
|
6
|
+
from edsl.scenarios.Scenario import Scenario
|
7
|
+
from edsl.jobs.Jobs import Jobs
|
8
|
+
|
9
|
+
|
10
|
+
class JobsComponentConstructor:
|
11
|
+
"Handles the creation of Agents, Scenarios, and LanguageModels in a job."
|
12
|
+
|
13
|
+
def __init__(self, jobs: "Jobs"):
|
14
|
+
self.jobs = jobs
|
15
|
+
|
16
|
+
def by(
|
17
|
+
self,
|
18
|
+
*args: Union[
|
19
|
+
"Agent",
|
20
|
+
"Scenario",
|
21
|
+
"LanguageModel",
|
22
|
+
Sequence[Union["Agent", "Scenario", "LanguageModel"]],
|
23
|
+
],
|
24
|
+
) -> "Jobs":
|
25
|
+
"""
|
26
|
+
Add Agents, Scenarios and LanguageModels to a job.
|
27
|
+
|
28
|
+
:param args: objects or a sequence (list, tuple, ...) of objects of the same type
|
29
|
+
|
30
|
+
If no objects of this type exist in the Jobs instance, it stores the new objects as a list in the corresponding attribute.
|
31
|
+
Otherwise, it combines the new objects with existing objects using the object's `__add__` method.
|
32
|
+
|
33
|
+
This 'by' is intended to create a fluent interface.
|
34
|
+
|
35
|
+
>>> from edsl.surveys import Survey
|
36
|
+
>>> from edsl.questions import QuestionFreeText
|
37
|
+
>>> q = QuestionFreeText(question_name="name", question_text="What is your name?")
|
38
|
+
>>> from edsl.jobs import Jobs
|
39
|
+
>>> j = Jobs(survey = Survey(questions=[q]))
|
40
|
+
>>> j
|
41
|
+
Jobs(survey=Survey(...), agents=AgentList([]), models=ModelList([]), scenarios=ScenarioList([]))
|
42
|
+
>>> from edsl import Agent; a = Agent(traits = {"status": "Sad"})
|
43
|
+
>>> j.by(a).agents
|
44
|
+
AgentList([Agent(traits = {'status': 'Sad'})])
|
45
|
+
|
46
|
+
|
47
|
+
Notes:
|
48
|
+
- all objects must implement the 'get_value', 'set_value', and `__add__` methods
|
49
|
+
- agents: traits of new agents are combined with traits of existing agents. New and existing agents should not have overlapping traits, and do not increase the # agents in the instance
|
50
|
+
- scenarios: traits of new scenarios are combined with traits of old existing. New scenarios will overwrite overlapping traits, and do not increase the number of scenarios in the instance
|
51
|
+
- models: new models overwrite old models.
|
52
|
+
"""
|
53
|
+
from edsl.results.Dataset import Dataset
|
54
|
+
|
55
|
+
if isinstance(
|
56
|
+
args[0], Dataset
|
57
|
+
): # let the user use a Dataset as if it were a ScenarioList
|
58
|
+
args = args[0].to_scenario_list()
|
59
|
+
|
60
|
+
passed_objects = self._turn_args_to_list(
|
61
|
+
args
|
62
|
+
) # objects can also be passed comma-separated
|
63
|
+
|
64
|
+
current_objects, objects_key = self._get_current_objects_of_this_type(
|
65
|
+
passed_objects[0]
|
66
|
+
)
|
67
|
+
|
68
|
+
if not current_objects:
|
69
|
+
new_objects = passed_objects
|
70
|
+
else:
|
71
|
+
new_objects = self._merge_objects(passed_objects, current_objects)
|
72
|
+
|
73
|
+
setattr(self.jobs, objects_key, new_objects) # update the job object
|
74
|
+
return self.jobs
|
75
|
+
|
76
|
+
@staticmethod
|
77
|
+
def _turn_args_to_list(args):
|
78
|
+
"""Return a list of the first argument if it is a sequence, otherwise returns a list of all the arguments.
|
79
|
+
|
80
|
+
Example:
|
81
|
+
|
82
|
+
>>> JobsComponentConstructor._turn_args_to_list([1,2,3])
|
83
|
+
[1, 2, 3]
|
84
|
+
|
85
|
+
"""
|
86
|
+
|
87
|
+
def did_user_pass_a_sequence(args):
|
88
|
+
"""Return True if the user passed a sequence, False otherwise.
|
89
|
+
|
90
|
+
Example:
|
91
|
+
|
92
|
+
>>> did_user_pass_a_sequence([1,2,3])
|
93
|
+
True
|
94
|
+
|
95
|
+
>>> did_user_pass_a_sequence(1)
|
96
|
+
False
|
97
|
+
"""
|
98
|
+
return len(args) == 1 and isinstance(args[0], Sequence)
|
99
|
+
|
100
|
+
if did_user_pass_a_sequence(args):
|
101
|
+
container_class = JobsComponentConstructor._get_container_class(args[0][0])
|
102
|
+
return container_class(args[0])
|
103
|
+
else:
|
104
|
+
container_class = JobsComponentConstructor._get_container_class(args[0])
|
105
|
+
return container_class(args)
|
106
|
+
|
107
|
+
def _get_current_objects_of_this_type(
|
108
|
+
self, object: Union["Agent", "Scenario", "LanguageModel"]
|
109
|
+
) -> tuple[list, str]:
|
110
|
+
from edsl.agents.Agent import Agent
|
111
|
+
from edsl.scenarios.Scenario import Scenario
|
112
|
+
from edsl.language_models.LanguageModel import LanguageModel
|
113
|
+
|
114
|
+
"""Return the current objects of the same type as the first argument.
|
115
|
+
|
116
|
+
>>> from edsl.jobs import Jobs
|
117
|
+
>>> j = JobsComponentConstructor(Jobs.example())
|
118
|
+
>>> j._get_current_objects_of_this_type(j.agents[0])
|
119
|
+
(AgentList([Agent(traits = {'status': 'Joyful'}), Agent(traits = {'status': 'Sad'})]), 'agents')
|
120
|
+
"""
|
121
|
+
class_to_key = {
|
122
|
+
Agent: "agents",
|
123
|
+
Scenario: "scenarios",
|
124
|
+
LanguageModel: "models",
|
125
|
+
}
|
126
|
+
for class_type in class_to_key:
|
127
|
+
if isinstance(object, class_type) or issubclass(
|
128
|
+
object.__class__, class_type
|
129
|
+
):
|
130
|
+
key = class_to_key[class_type]
|
131
|
+
break
|
132
|
+
else:
|
133
|
+
raise ValueError(
|
134
|
+
f"First argument must be an Agent, Scenario, or LanguageModel, not {object}"
|
135
|
+
)
|
136
|
+
current_objects = getattr(self.jobs, key, None)
|
137
|
+
return current_objects, key
|
138
|
+
|
139
|
+
@staticmethod
|
140
|
+
def _get_empty_container_object(object):
|
141
|
+
from edsl.agents.AgentList import AgentList
|
142
|
+
from edsl.scenarios.ScenarioList import ScenarioList
|
143
|
+
|
144
|
+
return {"Agent": AgentList([]), "Scenario": ScenarioList([])}.get(
|
145
|
+
object.__class__.__name__, []
|
146
|
+
)
|
147
|
+
|
148
|
+
@staticmethod
|
149
|
+
def _merge_objects(passed_objects, current_objects) -> list:
|
150
|
+
"""
|
151
|
+
Combine all the existing objects with the new objects.
|
152
|
+
|
153
|
+
For example, if the user passes in 3 agents,
|
154
|
+
and there are 2 existing agents, this will create 6 new agents
|
155
|
+
>>> from edsl.jobs import Jobs
|
156
|
+
>>> JobsComponentConstructor(Jobs(survey = []))._merge_objects([1,2,3], [4,5,6])
|
157
|
+
[5, 6, 7, 6, 7, 8, 7, 8, 9]
|
158
|
+
"""
|
159
|
+
new_objects = JobsComponentConstructor._get_empty_container_object(
|
160
|
+
passed_objects[0]
|
161
|
+
)
|
162
|
+
for current_object in current_objects:
|
163
|
+
for new_object in passed_objects:
|
164
|
+
new_objects.append(current_object + new_object)
|
165
|
+
return new_objects
|
166
|
+
|
167
|
+
@staticmethod
|
168
|
+
def _get_container_class(object):
|
169
|
+
from edsl.agents.AgentList import AgentList
|
170
|
+
from edsl.agents.Agent import Agent
|
171
|
+
from edsl.scenarios.Scenario import Scenario
|
172
|
+
from edsl.scenarios.ScenarioList import ScenarioList
|
173
|
+
from edsl.language_models.ModelList import ModelList
|
174
|
+
|
175
|
+
if isinstance(object, Agent):
|
176
|
+
return AgentList
|
177
|
+
elif isinstance(object, Scenario):
|
178
|
+
return ScenarioList
|
179
|
+
elif isinstance(object, ModelList):
|
180
|
+
return ModelList
|
181
|
+
else:
|
182
|
+
return list
|
183
|
+
|
184
|
+
|
185
|
+
if __name__ == "__main__":
|
186
|
+
"""Run the module's doctests."""
|
187
|
+
import doctest
|
188
|
+
|
189
|
+
doctest.testmod(optionflags=doctest.ELLIPSIS)
|
edsl/jobs/JobsPrompts.py
CHANGED
@@ -11,6 +11,8 @@ if TYPE_CHECKING:
|
|
11
11
|
# from edsl.scenarios.ScenarioList import ScenarioList
|
12
12
|
# from edsl.surveys.Survey import Survey
|
13
13
|
|
14
|
+
from edsl.jobs.FetchInvigilator import FetchInvigilator
|
15
|
+
|
14
16
|
|
15
17
|
class JobsPrompts:
|
16
18
|
def __init__(self, jobs: "Jobs"):
|
@@ -23,7 +25,7 @@ class JobsPrompts:
|
|
23
25
|
@property
|
24
26
|
def price_lookup(self):
|
25
27
|
if self._price_lookup is None:
|
26
|
-
from edsl import Coop
|
28
|
+
from edsl.coop.coop import Coop
|
27
29
|
|
28
30
|
c = Coop()
|
29
31
|
self._price_lookup = c.fetch_prices()
|
@@ -48,8 +50,8 @@ class JobsPrompts:
|
|
48
50
|
|
49
51
|
for interview_index, interview in enumerate(interviews):
|
50
52
|
invigilators = [
|
51
|
-
interview
|
52
|
-
for question in
|
53
|
+
FetchInvigilator(interview)(question)
|
54
|
+
for question in interview.survey.questions
|
53
55
|
]
|
54
56
|
for _, invigilator in enumerate(invigilators):
|
55
57
|
prompts = invigilator.get_prompts()
|
@@ -184,7 +186,7 @@ class JobsPrompts:
|
|
184
186
|
data = []
|
185
187
|
for interview in interviews:
|
186
188
|
invigilators = [
|
187
|
-
interview
|
189
|
+
FetchInvigilator(interview)(question)
|
188
190
|
for question in self.survey.questions
|
189
191
|
]
|
190
192
|
for invigilator in invigilators:
|