edsl 0.1.29__py3-none-any.whl → 0.1.29.dev1__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 +18 -18
- edsl/__init__.py +24 -24
- edsl/__version__.py +1 -1
- edsl/agents/Agent.py +41 -77
- edsl/agents/AgentList.py +6 -35
- edsl/agents/Invigilator.py +1 -19
- edsl/agents/InvigilatorBase.py +10 -15
- edsl/agents/PromptConstructionMixin.py +100 -342
- edsl/agents/descriptors.py +1 -2
- edsl/config.py +1 -2
- edsl/conjure/InputData.py +8 -39
- edsl/coop/coop.py +150 -187
- edsl/coop/utils.py +75 -43
- edsl/data/Cache.py +5 -19
- edsl/data/SQLiteDict.py +3 -11
- edsl/jobs/Answers.py +1 -15
- edsl/jobs/Jobs.py +46 -90
- edsl/jobs/buckets/ModelBuckets.py +2 -4
- edsl/jobs/buckets/TokenBucket.py +2 -1
- edsl/jobs/interviews/Interview.py +9 -3
- edsl/jobs/interviews/InterviewStatusMixin.py +3 -3
- edsl/jobs/interviews/InterviewTaskBuildingMixin.py +10 -15
- edsl/jobs/runners/JobsRunnerAsyncio.py +25 -21
- edsl/jobs/tasks/TaskHistory.py +3 -4
- edsl/language_models/LanguageModel.py +11 -5
- edsl/language_models/ModelList.py +3 -3
- edsl/language_models/repair.py +7 -8
- edsl/notebooks/Notebook.py +3 -40
- edsl/prompts/Prompt.py +19 -31
- edsl/questions/QuestionBase.py +13 -38
- edsl/questions/QuestionBudget.py +6 -5
- edsl/questions/QuestionCheckBox.py +3 -7
- edsl/questions/QuestionExtract.py +3 -5
- edsl/questions/QuestionFreeText.py +3 -3
- edsl/questions/QuestionFunctional.py +3 -0
- edsl/questions/QuestionList.py +4 -3
- edsl/questions/QuestionMultipleChoice.py +8 -16
- edsl/questions/QuestionNumerical.py +3 -4
- edsl/questions/QuestionRank.py +3 -5
- edsl/questions/__init__.py +3 -4
- edsl/questions/descriptors.py +2 -4
- edsl/questions/question_registry.py +31 -20
- edsl/questions/settings.py +1 -1
- edsl/results/Dataset.py +0 -31
- edsl/results/Result.py +74 -22
- edsl/results/Results.py +47 -97
- edsl/results/ResultsDBMixin.py +3 -7
- edsl/results/ResultsExportMixin.py +537 -22
- edsl/results/ResultsGGMixin.py +3 -3
- edsl/results/ResultsToolsMixin.py +5 -5
- edsl/scenarios/Scenario.py +6 -5
- edsl/scenarios/ScenarioList.py +11 -34
- edsl/scenarios/ScenarioListPdfMixin.py +1 -2
- edsl/scenarios/__init__.py +0 -1
- edsl/study/ObjectEntry.py +13 -89
- edsl/study/ProofOfWork.py +2 -5
- edsl/study/SnapShot.py +8 -4
- edsl/study/Study.py +14 -21
- edsl/study/__init__.py +0 -2
- edsl/surveys/MemoryPlan.py +4 -11
- edsl/surveys/Survey.py +7 -46
- edsl/surveys/SurveyExportMixin.py +2 -4
- edsl/surveys/SurveyFlowVisualizationMixin.py +4 -6
- edsl/tools/plotting.py +2 -4
- edsl/utilities/__init__.py +21 -21
- edsl/utilities/interface.py +45 -66
- edsl/utilities/utilities.py +13 -11
- {edsl-0.1.29.dist-info → edsl-0.1.29.dev1.dist-info}/METADATA +10 -11
- {edsl-0.1.29.dist-info → edsl-0.1.29.dev1.dist-info}/RECORD +72 -75
- edsl-0.1.29.dev1.dist-info/entry_points.txt +3 -0
- edsl/base/Base.py +0 -289
- edsl/results/DatasetExportMixin.py +0 -493
- edsl/scenarios/FileStore.py +0 -140
- edsl/scenarios/ScenarioListExportMixin.py +0 -32
- {edsl-0.1.29.dist-info → edsl-0.1.29.dev1.dist-info}/LICENSE +0 -0
- {edsl-0.1.29.dist-info → edsl-0.1.29.dev1.dist-info}/WHEEL +0 -0
@@ -2,6 +2,8 @@ from __future__ import annotations
|
|
2
2
|
from typing import Any
|
3
3
|
from edsl.questions.QuestionBase import QuestionBase
|
4
4
|
from edsl.questions.descriptors import AnswerTemplateDescriptor
|
5
|
+
from edsl.scenarios import Scenario
|
6
|
+
from edsl.utilities import random_string
|
5
7
|
|
6
8
|
|
7
9
|
class QuestionExtract(QuestionBase):
|
@@ -42,14 +44,12 @@ class QuestionExtract(QuestionBase):
|
|
42
44
|
self._validate_answer_extract(answer)
|
43
45
|
return answer
|
44
46
|
|
45
|
-
def _translate_answer_code_to_answer(self, answer, scenario:
|
47
|
+
def _translate_answer_code_to_answer(self, answer, scenario: Scenario = None):
|
46
48
|
"""Return the answer in a human-readable format."""
|
47
49
|
return answer
|
48
50
|
|
49
51
|
def _simulate_answer(self, human_readable: bool = True) -> dict[str, str]:
|
50
52
|
"""Simulate a valid answer for debugging purposes."""
|
51
|
-
from edsl.utilities.utilities import random_string
|
52
|
-
|
53
53
|
return {
|
54
54
|
"answer": {key: random_string() for key in self.answer_template.keys()},
|
55
55
|
"comment": random_string(),
|
@@ -106,8 +106,6 @@ def main():
|
|
106
106
|
q.to_dict()
|
107
107
|
assert q.from_dict(q.to_dict()) == q
|
108
108
|
|
109
|
-
|
110
|
-
if __name__ == "__main__":
|
111
109
|
import doctest
|
112
110
|
|
113
111
|
doctest.testmod(optionflags=doctest.ELLIPSIS)
|
@@ -2,6 +2,8 @@ from __future__ import annotations
|
|
2
2
|
import textwrap
|
3
3
|
from typing import Any, Optional
|
4
4
|
from edsl.questions.QuestionBase import QuestionBase
|
5
|
+
from edsl.scenarios import Scenario
|
6
|
+
from edsl.utilities import random_string
|
5
7
|
|
6
8
|
|
7
9
|
class QuestionFreeText(QuestionBase):
|
@@ -41,14 +43,12 @@ class QuestionFreeText(QuestionBase):
|
|
41
43
|
self._validate_answer_key_value(answer, "answer", str)
|
42
44
|
return answer
|
43
45
|
|
44
|
-
def _translate_answer_code_to_answer(self, answer, scenario:
|
46
|
+
def _translate_answer_code_to_answer(self, answer, scenario: Scenario = None):
|
45
47
|
"""Do nothing, because the answer is already in a human-readable format."""
|
46
48
|
return answer
|
47
49
|
|
48
50
|
def _simulate_answer(self, human_readable: bool = True) -> dict[str, str]:
|
49
51
|
"""Simulate a valid answer for debugging purposes."""
|
50
|
-
from edsl.utilities.utilities import random_string
|
51
|
-
|
52
52
|
return {"answer": random_string()}
|
53
53
|
|
54
54
|
@property
|
@@ -1,7 +1,10 @@
|
|
1
1
|
from typing import Optional, Callable
|
2
|
+
from edsl.questions.QuestionBase import QuestionBase
|
3
|
+
from edsl.questions.descriptors import FunctionDescriptor
|
2
4
|
import inspect
|
3
5
|
|
4
6
|
from edsl.questions.QuestionBase import QuestionBase
|
7
|
+
from edsl.questions.descriptors import FunctionDescriptor
|
5
8
|
|
6
9
|
from edsl.utilities.restricted_python import create_restricted_function
|
7
10
|
|
edsl/questions/QuestionList.py
CHANGED
@@ -5,6 +5,9 @@ from typing import Any, Optional, Union
|
|
5
5
|
from edsl.questions.QuestionBase import QuestionBase
|
6
6
|
from edsl.questions.descriptors import IntegerOrNoneDescriptor
|
7
7
|
|
8
|
+
from edsl.scenarios import Scenario
|
9
|
+
from edsl.utilities import random_string
|
10
|
+
|
8
11
|
|
9
12
|
class QuestionList(QuestionBase):
|
10
13
|
"""This question prompts the agent to answer by providing a list of items as comma-separated strings."""
|
@@ -39,15 +42,13 @@ class QuestionList(QuestionBase):
|
|
39
42
|
self._validate_answer_list(answer)
|
40
43
|
return answer
|
41
44
|
|
42
|
-
def _translate_answer_code_to_answer(self, answer, scenario:
|
45
|
+
def _translate_answer_code_to_answer(self, answer, scenario: Scenario = None):
|
43
46
|
"""There is no answer code."""
|
44
47
|
return answer
|
45
48
|
|
46
49
|
def _simulate_answer(self, human_readable: bool = True):
|
47
50
|
"""Simulate a valid answer for debugging purposes (what the validator expects)."""
|
48
51
|
num_items = random.randint(1, self.max_list_items or 2)
|
49
|
-
from edsl.utilities.utilities import random_string
|
50
|
-
|
51
52
|
return {"answer": [random_string() for _ in range(num_items)]}
|
52
53
|
|
53
54
|
@property
|
@@ -1,12 +1,13 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
import
|
3
|
-
from typing import Union
|
2
|
+
from typing import Optional, Union
|
4
3
|
import random
|
5
4
|
|
6
5
|
from jinja2 import Template
|
7
6
|
|
8
|
-
from edsl.
|
7
|
+
from edsl.utilities import random_string
|
9
8
|
from edsl.questions.descriptors import QuestionOptionsDescriptor
|
9
|
+
from edsl.questions.QuestionBase import QuestionBase
|
10
|
+
from edsl.scenarios import Scenario
|
10
11
|
|
11
12
|
|
12
13
|
class QuestionMultipleChoice(QuestionBase):
|
@@ -14,9 +15,9 @@ class QuestionMultipleChoice(QuestionBase):
|
|
14
15
|
|
15
16
|
question_type = "multiple_choice"
|
16
17
|
purpose = "When options are known and limited"
|
17
|
-
question_options: Union[
|
18
|
-
|
19
|
-
)
|
18
|
+
question_options: Union[
|
19
|
+
list[str], list[list], list[float], list[int]
|
20
|
+
] = QuestionOptionsDescriptor()
|
20
21
|
|
21
22
|
def __init__(
|
22
23
|
self,
|
@@ -46,12 +47,8 @@ class QuestionMultipleChoice(QuestionBase):
|
|
46
47
|
self._validate_answer_multiple_choice(answer)
|
47
48
|
return answer
|
48
49
|
|
49
|
-
def _translate_answer_code_to_answer(
|
50
|
-
self, answer_code, scenario: "Scenario" = None
|
51
|
-
):
|
50
|
+
def _translate_answer_code_to_answer(self, answer_code, scenario: Scenario = None):
|
52
51
|
"""Translate the answer code to the actual answer."""
|
53
|
-
from edsl.scenarios.Scenario import Scenario
|
54
|
-
|
55
52
|
scenario = scenario or Scenario()
|
56
53
|
translated_options = [
|
57
54
|
Template(str(option)).render(scenario) for option in self.question_options
|
@@ -62,8 +59,6 @@ class QuestionMultipleChoice(QuestionBase):
|
|
62
59
|
self, human_readable: bool = True
|
63
60
|
) -> dict[str, Union[int, str]]:
|
64
61
|
"""Simulate a valid answer for debugging purposes."""
|
65
|
-
from edsl.utilities.utilities import random_string
|
66
|
-
|
67
62
|
if human_readable:
|
68
63
|
answer = random.choice(self.question_options)
|
69
64
|
else:
|
@@ -75,7 +70,6 @@ class QuestionMultipleChoice(QuestionBase):
|
|
75
70
|
|
76
71
|
@property
|
77
72
|
def question_html_content(self) -> str:
|
78
|
-
|
79
73
|
if hasattr(self, "option_labels"):
|
80
74
|
option_labels = self.option_labels
|
81
75
|
else:
|
@@ -133,8 +127,6 @@ def main():
|
|
133
127
|
q.to_dict()
|
134
128
|
assert q.from_dict(q.to_dict()) == q
|
135
129
|
|
136
|
-
|
137
|
-
if __name__ == "__main__":
|
138
130
|
import doctest
|
139
131
|
|
140
132
|
doctest.testmod(optionflags=doctest.ELLIPSIS)
|
@@ -2,10 +2,11 @@ from __future__ import annotations
|
|
2
2
|
import textwrap
|
3
3
|
from random import uniform
|
4
4
|
from typing import Any, Optional, Union
|
5
|
-
|
6
5
|
from edsl.exceptions import QuestionAnswerValidationError
|
7
6
|
from edsl.questions.QuestionBase import QuestionBase
|
8
7
|
from edsl.questions.descriptors import NumericalOrNoneDescriptor
|
8
|
+
from edsl.scenarios import Scenario
|
9
|
+
from edsl.utilities import random_string
|
9
10
|
|
10
11
|
|
11
12
|
class QuestionNumerical(QuestionBase):
|
@@ -47,14 +48,12 @@ class QuestionNumerical(QuestionBase):
|
|
47
48
|
self._validate_answer_numerical(answer)
|
48
49
|
return answer
|
49
50
|
|
50
|
-
def _translate_answer_code_to_answer(self, answer, scenario:
|
51
|
+
def _translate_answer_code_to_answer(self, answer, scenario: Scenario = None):
|
51
52
|
"""There is no answer code."""
|
52
53
|
return answer
|
53
54
|
|
54
55
|
def _simulate_answer(self, human_readable: bool = True):
|
55
56
|
"""Simulate a valid answer for debugging purposes."""
|
56
|
-
from edsl.utilities.utilities import random_string
|
57
|
-
|
58
57
|
return {
|
59
58
|
"answer": uniform(self.min_value, self.max_value),
|
60
59
|
"comment": random_string(),
|
edsl/questions/QuestionRank.py
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
import random
|
3
|
+
import textwrap
|
3
4
|
from jinja2 import Template
|
4
5
|
from typing import Any, Optional, Union
|
5
6
|
from edsl.questions.QuestionBase import QuestionBase
|
6
7
|
from edsl.exceptions import QuestionAnswerValidationError
|
7
|
-
|
8
|
+
from edsl.scenarios import Scenario
|
9
|
+
from edsl.utilities.utilities import random_string
|
8
10
|
from edsl.questions.descriptors import (
|
9
11
|
QuestionOptionsDescriptor,
|
10
12
|
NumSelectionsDescriptor,
|
@@ -53,8 +55,6 @@ class QuestionRank(QuestionBase):
|
|
53
55
|
self, answer_codes, scenario: Scenario = None
|
54
56
|
) -> list[str]:
|
55
57
|
"""Translate the answer code to the actual answer."""
|
56
|
-
from edsl.scenarios import Scenario
|
57
|
-
|
58
58
|
scenario = scenario or Scenario()
|
59
59
|
translated_options = [
|
60
60
|
Template(option).render(scenario) for option in self.question_options
|
@@ -66,8 +66,6 @@ class QuestionRank(QuestionBase):
|
|
66
66
|
|
67
67
|
def _simulate_answer(self, human_readable=True) -> dict[str, Union[int, str]]:
|
68
68
|
"""Simulate a valid answer for debugging purposes."""
|
69
|
-
from edsl.utilities.utilities import random_string
|
70
|
-
|
71
69
|
if human_readable:
|
72
70
|
selected = random.sample(self.question_options, self.num_selections)
|
73
71
|
else:
|
edsl/questions/__init__.py
CHANGED
@@ -10,18 +10,17 @@ from edsl.questions.QuestionBudget import QuestionBudget
|
|
10
10
|
from edsl.questions.QuestionCheckBox import QuestionCheckBox
|
11
11
|
from edsl.questions.QuestionExtract import QuestionExtract
|
12
12
|
from edsl.questions.QuestionFreeText import QuestionFreeText
|
13
|
-
|
14
13
|
from edsl.questions.QuestionFunctional import QuestionFunctional
|
15
14
|
from edsl.questions.QuestionList import QuestionList
|
16
15
|
from edsl.questions.QuestionMultipleChoice import QuestionMultipleChoice
|
17
16
|
from edsl.questions.QuestionNumerical import QuestionNumerical
|
18
17
|
from edsl.questions.QuestionRank import QuestionRank
|
19
18
|
|
20
|
-
#
|
19
|
+
# Questions derived from core questions
|
21
20
|
from edsl.questions.derived.QuestionLikertFive import QuestionLikertFive
|
22
21
|
from edsl.questions.derived.QuestionLinearScale import QuestionLinearScale
|
23
22
|
from edsl.questions.derived.QuestionTopK import QuestionTopK
|
24
23
|
from edsl.questions.derived.QuestionYesNo import QuestionYesNo
|
25
24
|
|
26
|
-
#
|
27
|
-
|
25
|
+
# Compose Questions
|
26
|
+
from edsl.questions.compose_questions import compose_questions
|
edsl/questions/descriptors.py
CHANGED
@@ -8,7 +8,9 @@ from edsl.exceptions import (
|
|
8
8
|
QuestionAnswerValidationError,
|
9
9
|
)
|
10
10
|
from edsl.questions.settings import Settings
|
11
|
+
from edsl.utilities.utilities import is_valid_variable_name
|
11
12
|
|
13
|
+
from edsl.prompts import get_classes
|
12
14
|
|
13
15
|
################################
|
14
16
|
# Helper functions
|
@@ -54,8 +56,6 @@ class BaseDescriptor(ABC):
|
|
54
56
|
def __set__(self, instance, value: Any) -> None:
|
55
57
|
"""Set the value of the attribute."""
|
56
58
|
self.validate(value, instance)
|
57
|
-
from edsl.prompts.registry import get_classes
|
58
|
-
|
59
59
|
instance.__dict__[self.name] = value
|
60
60
|
if self.name == "_instructions":
|
61
61
|
instructions = value
|
@@ -231,8 +231,6 @@ class QuestionNameDescriptor(BaseDescriptor):
|
|
231
231
|
|
232
232
|
def validate(self, value, instance):
|
233
233
|
"""Validate the value is a valid variable name."""
|
234
|
-
from edsl.utilities.utilities import is_valid_variable_name
|
235
|
-
|
236
234
|
if not is_valid_variable_name(value):
|
237
235
|
raise QuestionCreationValidationError(
|
238
236
|
f"`question_name` is not a valid variable name (got {value})."
|
@@ -1,10 +1,10 @@
|
|
1
1
|
"""This module provides a factory class for creating question objects."""
|
2
2
|
|
3
3
|
import textwrap
|
4
|
-
from
|
5
|
-
from typing import Any, Optional, Union
|
6
|
-
|
4
|
+
from typing import Union
|
7
5
|
|
6
|
+
from edsl.exceptions import QuestionSerializationError
|
7
|
+
from edsl.exceptions import QuestionCreationValidationError
|
8
8
|
from edsl.questions.QuestionBase import RegisterQuestionsMeta
|
9
9
|
|
10
10
|
|
@@ -60,35 +60,46 @@ class Question(metaclass=Meta):
|
|
60
60
|
return q.example()
|
61
61
|
|
62
62
|
@classmethod
|
63
|
-
def pull(cls,
|
63
|
+
def pull(cls, id_or_url: str):
|
64
64
|
"""Pull the object from coop."""
|
65
65
|
from edsl.coop import Coop
|
66
66
|
|
67
|
-
|
68
|
-
|
67
|
+
c = Coop()
|
68
|
+
if c.url in id_or_url:
|
69
|
+
id = id_or_url.split("/")[-1]
|
70
|
+
else:
|
71
|
+
id = id_or_url
|
72
|
+
from edsl.questions.QuestionBase import QuestionBase
|
73
|
+
|
74
|
+
return c._get_base(QuestionBase, id)
|
69
75
|
|
70
76
|
@classmethod
|
71
|
-
def delete(cls,
|
77
|
+
def delete(cls, id_or_url: str):
|
72
78
|
"""Delete the object from coop."""
|
73
79
|
from edsl.coop import Coop
|
74
80
|
|
75
|
-
|
76
|
-
|
81
|
+
c = Coop()
|
82
|
+
if c.url in id_or_url:
|
83
|
+
id = id_or_url.split("/")[-1]
|
84
|
+
else:
|
85
|
+
id = id_or_url
|
86
|
+
from edsl.questions.QuestionBase import QuestionBase
|
87
|
+
|
88
|
+
return c._delete_base(QuestionBase, id)
|
77
89
|
|
78
90
|
@classmethod
|
79
|
-
def
|
80
|
-
|
81
|
-
uuid: Optional[Union[str, UUID]] = None,
|
82
|
-
url: Optional[str] = None,
|
83
|
-
description: Optional[str] = None,
|
84
|
-
value: Optional[Any] = None,
|
85
|
-
visibility: Optional[str] = None,
|
86
|
-
):
|
87
|
-
"""Patch the object on coop."""
|
91
|
+
def update(cls, id_or_url: str, visibility: str):
|
92
|
+
"""Update the object on coop."""
|
88
93
|
from edsl.coop import Coop
|
89
94
|
|
90
|
-
|
91
|
-
|
95
|
+
c = Coop()
|
96
|
+
if c.url in id_or_url:
|
97
|
+
id = id_or_url.split("/")[-1]
|
98
|
+
else:
|
99
|
+
id = id_or_url
|
100
|
+
from edsl.questions.QuestionBase import QuestionBase
|
101
|
+
|
102
|
+
return c._update_base(QuestionBase, id, visibility)
|
92
103
|
|
93
104
|
@classmethod
|
94
105
|
def available(cls, show_class_names: bool = False) -> Union[list, dict]:
|
edsl/questions/settings.py
CHANGED
edsl/results/Dataset.py
CHANGED
@@ -78,28 +78,6 @@ class Dataset(UserList, ResultsExportMixin):
|
|
78
78
|
|
79
79
|
return get_values(self.data[0])[0]
|
80
80
|
|
81
|
-
def select(self, *keys):
|
82
|
-
"""Return a new dataset with only the selected keys.
|
83
|
-
|
84
|
-
:param keys: The keys to select.
|
85
|
-
|
86
|
-
>>> d = Dataset([{'a.b':[1,2,3,4]}, {'c.d':[5,6,7,8]}])
|
87
|
-
>>> d.select('a.b')
|
88
|
-
Dataset([{'a.b': [1, 2, 3, 4]}])
|
89
|
-
|
90
|
-
>>> d.select('a.b', 'c.d')
|
91
|
-
Dataset([{'a.b': [1, 2, 3, 4]}, {'c.d': [5, 6, 7, 8]}])
|
92
|
-
"""
|
93
|
-
if isinstance(keys, str):
|
94
|
-
keys = [keys]
|
95
|
-
|
96
|
-
new_data = []
|
97
|
-
for observation in self.data:
|
98
|
-
observation_key = list(observation.keys())[0]
|
99
|
-
if observation_key in keys:
|
100
|
-
new_data.append(observation)
|
101
|
-
return Dataset(new_data)
|
102
|
-
|
103
81
|
def _repr_html_(self) -> str:
|
104
82
|
"""Return an HTML representation of the dataset."""
|
105
83
|
from edsl.utilities.utilities import data_to_html
|
@@ -245,15 +223,6 @@ class Dataset(UserList, ResultsExportMixin):
|
|
245
223
|
|
246
224
|
return Dataset(new_data)
|
247
225
|
|
248
|
-
@classmethod
|
249
|
-
def example(self):
|
250
|
-
"""Return an example dataset.
|
251
|
-
|
252
|
-
>>> Dataset.example()
|
253
|
-
Dataset([{'a': [1, 2, 3, 4]}, {'b': [4, 3, 2, 1]}])
|
254
|
-
"""
|
255
|
-
return Dataset([{"a": [1, 2, 3, 4]}, {"b": [4, 3, 2, 1]}])
|
256
|
-
|
257
226
|
|
258
227
|
if __name__ == "__main__":
|
259
228
|
import doctest
|
edsl/results/Result.py
CHANGED
@@ -3,7 +3,16 @@ from __future__ import annotations
|
|
3
3
|
from collections import UserDict
|
4
4
|
from typing import Any, Type, Callable, Optional
|
5
5
|
from collections import UserDict
|
6
|
+
|
7
|
+
from rich.table import Table
|
8
|
+
|
9
|
+
from IPython.display import display
|
10
|
+
|
11
|
+
from edsl.agents import Agent
|
12
|
+
from edsl.language_models import LanguageModel
|
13
|
+
from edsl.scenarios import Scenario
|
6
14
|
from edsl.Base import Base
|
15
|
+
from edsl.prompts import Prompt
|
7
16
|
from edsl.utilities.decorators import add_edsl_version, remove_edsl_version
|
8
17
|
|
9
18
|
|
@@ -12,8 +21,6 @@ class PromptDict(UserDict):
|
|
12
21
|
|
13
22
|
def rich_print(self):
|
14
23
|
"""Display an object as a table."""
|
15
|
-
from rich.table import Table
|
16
|
-
|
17
24
|
table = Table(title="")
|
18
25
|
table.add_column("Attribute", style="bold")
|
19
26
|
table.add_column("Value")
|
@@ -64,9 +71,9 @@ class Result(Base, UserDict):
|
|
64
71
|
|
65
72
|
def __init__(
|
66
73
|
self,
|
67
|
-
agent:
|
68
|
-
scenario:
|
69
|
-
model: Type[
|
74
|
+
agent: Agent,
|
75
|
+
scenario: Scenario,
|
76
|
+
model: Type[LanguageModel],
|
70
77
|
iteration: int,
|
71
78
|
answer: str,
|
72
79
|
prompt: dict[str, str] = None,
|
@@ -145,15 +152,15 @@ class Result(Base, UserDict):
|
|
145
152
|
if key in self.question_to_attributes:
|
146
153
|
# You might be tempted to just use the naked key
|
147
154
|
# but this is a bad idea because it pollutes the namespace
|
148
|
-
question_text_dict[
|
149
|
-
|
150
|
-
|
151
|
-
question_options_dict[
|
152
|
-
|
153
|
-
|
154
|
-
question_type_dict[
|
155
|
-
|
156
|
-
|
155
|
+
question_text_dict[
|
156
|
+
key + "_question_text"
|
157
|
+
] = self.question_to_attributes[key]["question_text"]
|
158
|
+
question_options_dict[
|
159
|
+
key + "_question_options"
|
160
|
+
] = self.question_to_attributes[key]["question_options"]
|
161
|
+
question_type_dict[
|
162
|
+
key + "_question_type"
|
163
|
+
] = self.question_to_attributes[key]["question_type"]
|
157
164
|
|
158
165
|
return {
|
159
166
|
"agent": self.agent.traits
|
@@ -271,12 +278,6 @@ class Result(Base, UserDict):
|
|
271
278
|
@remove_edsl_version
|
272
279
|
def from_dict(self, json_dict: dict) -> Result:
|
273
280
|
"""Return a Result object from a dictionary representation."""
|
274
|
-
|
275
|
-
from edsl import Agent
|
276
|
-
from edsl import Scenario
|
277
|
-
from edsl.language_models.LanguageModel import LanguageModel
|
278
|
-
from edsl.prompts.Prompt import Prompt
|
279
|
-
|
280
281
|
prompt_data = json_dict.get("prompt", {})
|
281
282
|
prompt_d = {}
|
282
283
|
for prompt_name, prompt_obj in prompt_data.items():
|
@@ -300,7 +301,6 @@ class Result(Base, UserDict):
|
|
300
301
|
"""Display an object as a table."""
|
301
302
|
# from edsl.utilities import print_dict_with_rich
|
302
303
|
from rich import print
|
303
|
-
from rich.table import Table
|
304
304
|
|
305
305
|
table = Table(title="Result")
|
306
306
|
table.add_column("Attribute", style="bold")
|
@@ -325,7 +325,7 @@ class Result(Base, UserDict):
|
|
325
325
|
@classmethod
|
326
326
|
def example(cls):
|
327
327
|
"""Return an example Result object."""
|
328
|
-
from edsl.results
|
328
|
+
from edsl.results import Results
|
329
329
|
|
330
330
|
return Results.example()[0]
|
331
331
|
|
@@ -350,7 +350,59 @@ class Result(Base, UserDict):
|
|
350
350
|
return scoring_function(**params)
|
351
351
|
|
352
352
|
|
353
|
+
def main():
|
354
|
+
"""Run the main function."""
|
355
|
+
from edsl.results.Result import Result
|
356
|
+
import json
|
357
|
+
|
358
|
+
print("Being imported")
|
359
|
+
json_string = """
|
360
|
+
{
|
361
|
+
"agent": {
|
362
|
+
"traits": {
|
363
|
+
"status": "Unhappy"
|
364
|
+
}
|
365
|
+
},
|
366
|
+
"scenario": {
|
367
|
+
"period": "morning"
|
368
|
+
},
|
369
|
+
"model": {
|
370
|
+
"model": "gpt-3.5-turbo",
|
371
|
+
"parameters": {
|
372
|
+
"temperature": 0.5,
|
373
|
+
"max_tokens": 1000,
|
374
|
+
"top_p": 1,
|
375
|
+
"frequency_penalty": 0,
|
376
|
+
"presence_penalty": 0,
|
377
|
+
"use_cache": true
|
378
|
+
}
|
379
|
+
},
|
380
|
+
"iteration": 0,
|
381
|
+
"answer": {
|
382
|
+
"how_feeling": "Bad"
|
383
|
+
},
|
384
|
+
"prompt": {"how_feeling_user_prompt": "How are you feeling today?", "how_feeling_system_prompt": "Answer the question"}
|
385
|
+
}
|
386
|
+
"""
|
387
|
+
|
388
|
+
result = Result.from_dict(json.loads(json_string))
|
389
|
+
|
390
|
+
result.sub_dicts
|
391
|
+
assert result.combined_dict["how_feeling"] == "Bad"
|
392
|
+
|
393
|
+
result.combined_dict
|
394
|
+
assert result.get_value("answer", "how_feeling") == "Bad"
|
395
|
+
|
396
|
+
result.key_to_data_type
|
397
|
+
print(result)
|
398
|
+
|
399
|
+
assert result == result.copy()
|
400
|
+
|
401
|
+
result.to_dict()
|
402
|
+
|
403
|
+
|
353
404
|
if __name__ == "__main__":
|
405
|
+
# print(Result.example())
|
354
406
|
import doctest
|
355
407
|
|
356
408
|
doctest.testmod(optionflags=doctest.ELLIPSIS)
|