edsl 0.1.58__py3-none-any.whl → 0.1.59__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/__version__.py +1 -1
- edsl/agents/agent.py +23 -4
- edsl/agents/agent_list.py +36 -6
- edsl/coop/coop.py +103 -1
- edsl/dataset/dataset.py +74 -0
- edsl/dataset/dataset_operations_mixin.py +67 -62
- edsl/inference_services/services/test_service.py +1 -1
- edsl/interviews/exception_tracking.py +66 -20
- edsl/invigilators/invigilators.py +5 -1
- edsl/invigilators/prompt_constructor.py +299 -136
- edsl/jobs/html_table_job_logger.py +18 -1
- edsl/jobs/jobs_pricing_estimation.py +6 -2
- edsl/jobs/jobs_remote_inference_logger.py +2 -0
- edsl/jobs/remote_inference.py +34 -7
- edsl/language_models/language_model.py +39 -2
- edsl/prompts/prompt.py +1 -0
- edsl/questions/question_list.py +76 -20
- edsl/results/results.py +8 -1
- edsl/scenarios/file_store.py +8 -12
- edsl/scenarios/scenario.py +50 -2
- edsl/scenarios/scenario_list.py +34 -12
- edsl/surveys/survey.py +4 -0
- edsl/tasks/task_history.py +180 -6
- edsl/utilities/wikipedia.py +194 -0
- {edsl-0.1.58.dist-info → edsl-0.1.59.dist-info}/METADATA +4 -3
- {edsl-0.1.58.dist-info → edsl-0.1.59.dist-info}/RECORD +29 -28
- {edsl-0.1.58.dist-info → edsl-0.1.59.dist-info}/LICENSE +0 -0
- {edsl-0.1.58.dist-info → edsl-0.1.59.dist-info}/WHEEL +0 -0
- {edsl-0.1.58.dist-info → edsl-0.1.59.dist-info}/entry_points.txt +0 -0
@@ -16,8 +16,9 @@ class InterviewExceptionEntry:
|
|
16
16
|
invigilator: "InvigilatorBase",
|
17
17
|
traceback_format="text",
|
18
18
|
answers=None,
|
19
|
+
time=None, # Added time parameter for deserialization
|
19
20
|
):
|
20
|
-
self.time = datetime.datetime.now().isoformat()
|
21
|
+
self.time = time or datetime.datetime.now().isoformat()
|
21
22
|
self.exception = exception
|
22
23
|
self.invigilator = invigilator
|
23
24
|
self.traceback_format = traceback_format
|
@@ -130,7 +131,12 @@ class InterviewExceptionEntry:
|
|
130
131
|
'Traceback (most recent call last):...'
|
131
132
|
"""
|
132
133
|
e = self.exception
|
133
|
-
|
134
|
+
# Check if the exception has a traceback attribute
|
135
|
+
if hasattr(e, "__traceback__") and e.__traceback__:
|
136
|
+
tb_str = "".join(traceback.format_exception(type(e), e, e.__traceback__))
|
137
|
+
else:
|
138
|
+
# Use the message as traceback if no traceback available
|
139
|
+
tb_str = f"Exception: {str(e)}"
|
134
140
|
return tb_str
|
135
141
|
|
136
142
|
@property
|
@@ -144,14 +150,19 @@ class InterviewExceptionEntry:
|
|
144
150
|
|
145
151
|
console = Console(file=html_output, record=True)
|
146
152
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
153
|
+
# Check if the exception has a traceback attribute
|
154
|
+
if hasattr(self.exception, "__traceback__") and self.exception.__traceback__:
|
155
|
+
tb = Traceback.from_exception(
|
156
|
+
type(self.exception),
|
157
|
+
self.exception,
|
158
|
+
self.exception.__traceback__,
|
159
|
+
show_locals=True,
|
160
|
+
)
|
161
|
+
console.print(tb)
|
162
|
+
return html_output.getvalue()
|
163
|
+
else:
|
164
|
+
# Return a simple string if no traceback available
|
165
|
+
return f"<pre>Exception: {str(self.exception)}</pre>"
|
155
166
|
|
156
167
|
@staticmethod
|
157
168
|
def serialize_exception(exception: Exception) -> dict:
|
@@ -160,14 +171,25 @@ class InterviewExceptionEntry:
|
|
160
171
|
>>> entry = InterviewExceptionEntry.example()
|
161
172
|
>>> _ = entry.serialize_exception(entry.exception)
|
162
173
|
"""
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
174
|
+
# Store the original exception type for proper reconstruction
|
175
|
+
exception_type = type(exception).__name__
|
176
|
+
module_name = getattr(type(exception), "__module__", "builtins")
|
177
|
+
|
178
|
+
# Extract traceback if available
|
179
|
+
if hasattr(exception, "__traceback__") and exception.__traceback__:
|
180
|
+
tb_str = "".join(
|
167
181
|
traceback.format_exception(
|
168
182
|
type(exception), exception, exception.__traceback__
|
169
183
|
)
|
170
|
-
)
|
184
|
+
)
|
185
|
+
else:
|
186
|
+
tb_str = f"Exception: {str(exception)}"
|
187
|
+
|
188
|
+
return {
|
189
|
+
"type": exception_type,
|
190
|
+
"module": module_name,
|
191
|
+
"message": str(exception),
|
192
|
+
"traceback": tb_str,
|
171
193
|
}
|
172
194
|
|
173
195
|
@staticmethod
|
@@ -177,11 +199,31 @@ class InterviewExceptionEntry:
|
|
177
199
|
>>> entry = InterviewExceptionEntry.example()
|
178
200
|
>>> _ = entry.deserialize_exception(entry.to_dict()["exception"])
|
179
201
|
"""
|
202
|
+
exception_type = data.get("type", "Exception")
|
203
|
+
module_name = data.get("module", "builtins")
|
204
|
+
message = data.get("message", "")
|
205
|
+
|
180
206
|
try:
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
207
|
+
# Try to import the module and get the exception class
|
208
|
+
# if module_name != "builtins":
|
209
|
+
# import importlib
|
210
|
+
|
211
|
+
# module = importlib.import_module(module_name)
|
212
|
+
# exception_class = getattr(module, exception_type, Exception)
|
213
|
+
# else:
|
214
|
+
# # Look for exception in builtins
|
215
|
+
import builtins
|
216
|
+
|
217
|
+
exception_class = getattr(builtins, exception_type, Exception)
|
218
|
+
|
219
|
+
except (ImportError, AttributeError):
|
220
|
+
# Fall back to a generic Exception but preserve the type name
|
221
|
+
exception = Exception(message)
|
222
|
+
exception.__class__.__name__ = exception_type
|
223
|
+
return exception
|
224
|
+
|
225
|
+
# Create instance of the original exception type if possible
|
226
|
+
return exception_class(message)
|
185
227
|
|
186
228
|
def to_dict(self) -> dict:
|
187
229
|
"""Return the exception as a dictionary.
|
@@ -221,7 +263,11 @@ class InterviewExceptionEntry:
|
|
221
263
|
invigilator = None
|
222
264
|
else:
|
223
265
|
invigilator = InvigilatorAI.from_dict(data["invigilator"])
|
224
|
-
|
266
|
+
|
267
|
+
# Use the original timestamp from serialization
|
268
|
+
time = data.get("time")
|
269
|
+
|
270
|
+
return cls(exception=exception, invigilator=invigilator, time=time)
|
225
271
|
|
226
272
|
|
227
273
|
class InterviewExceptionCollection(UserDict):
|
@@ -105,7 +105,11 @@ class InvigilatorBase(ABC):
|
|
105
105
|
value = getattr(self, attr)
|
106
106
|
if value is None:
|
107
107
|
return None
|
108
|
-
if hasattr(value, "
|
108
|
+
if attr == "scenario" and hasattr(value, "offload"):
|
109
|
+
# Use the scenario's offload method to replace base64_string values
|
110
|
+
offloaded = value.offload()
|
111
|
+
return offloaded.to_dict()
|
112
|
+
elif hasattr(value, "to_dict"):
|
109
113
|
return value.to_dict()
|
110
114
|
if isinstance(value, (int, float, str, bool, dict, list)):
|
111
115
|
return value
|