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.
@@ -43,6 +43,7 @@ class TaskHistory(RepresentationMixin):
43
43
  - Generates interactive HTML reports with filtering and drill-down
44
44
  - Computes statistics across interviews (by model, question type, etc.)
45
45
  - Exports to various formats (HTML, notebook, etc.)
46
+ - Memory optimization via offloading of large file content
46
47
  """
47
48
 
48
49
  def __init__(
@@ -191,8 +192,22 @@ class TaskHistory(RepresentationMixin):
191
192
  """Return a string representation of the TaskHistory."""
192
193
  return f"TaskHistory(interviews={self.total_interviews})."
193
194
 
194
- def to_dict(self, add_edsl_version=True):
195
- """Return the TaskHistory as a dictionary."""
195
+ def to_dict(self, add_edsl_version=True, offload_content=False):
196
+ """
197
+ Return the TaskHistory as a dictionary.
198
+
199
+ Parameters:
200
+ add_edsl_version: Whether to include EDSL version in the output
201
+ offload_content: Whether to offload large file content like videos and images
202
+ to reduce memory usage
203
+
204
+ Returns:
205
+ A dictionary representation of this TaskHistory instance
206
+ """
207
+ # Offload large file content if requested
208
+ if offload_content:
209
+ self.offload_files_content()
210
+
196
211
  # Serialize each interview object
197
212
  interview_dicts = []
198
213
  for i in self.total_interviews:
@@ -255,27 +270,60 @@ class TaskHistory(RepresentationMixin):
255
270
  InterviewExceptionCollection,
256
271
  )
257
272
 
273
+ # Store the original data in full
274
+ self._original_data = data
275
+
276
+ # Preserve the original interview id
277
+ self._interview_id = data.get("id", None)
278
+
279
+ # Store exceptions using the original data structure
280
+ # This ensures when we re-serialize, we keep original data intact
281
+ self._exceptions_data = data.get("exceptions", {})
282
+
283
+ # Create the InterviewExceptionCollection for runtime use
258
284
  exceptions_data = data.get("exceptions", {})
259
285
  self.exceptions = (
260
286
  InterviewExceptionCollection.from_dict(exceptions_data)
261
287
  if exceptions_data
262
288
  else InterviewExceptionCollection()
263
289
  )
290
+
291
+ # Store other fields
264
292
  self.task_status_logs = data.get("task_status_logs", {})
265
293
  self.model = data.get("model", {})
266
294
  self.survey = data.get("survey", {})
267
295
 
268
296
  def to_dict(self, add_edsl_version=True):
269
- return {
297
+ # Use the original exceptions data structure when serializing again
298
+ # This preserves all exception details exactly as they were
299
+ data = {
270
300
  "type": "InterviewReference",
271
- "exceptions": self.exceptions.to_dict()
272
- if hasattr(self.exceptions, "to_dict")
273
- else self.exceptions,
301
+ "exceptions": self._exceptions_data
302
+ if hasattr(self, "_exceptions_data")
303
+ else (
304
+ self.exceptions.to_dict()
305
+ if hasattr(self.exceptions, "to_dict")
306
+ else self.exceptions
307
+ ),
274
308
  "task_status_logs": self.task_status_logs,
275
309
  "model": self.model,
276
310
  "survey": self.survey,
277
311
  }
278
312
 
313
+ # Preserve the original interview id if it exists
314
+ if self._interview_id:
315
+ data["id"] = self._interview_id
316
+
317
+ # Preserve original version info
318
+ if (
319
+ add_edsl_version
320
+ and hasattr(self, "_original_data")
321
+ and "edsl_version" in self._original_data
322
+ ):
323
+ data["edsl_version"] = self._original_data["edsl_version"]
324
+
325
+ return data
326
+
279
327
  # Create the reference and add it directly
280
328
  ref = DeserializedInterviewRef(interview_data)
281
329
  instance.total_interviews.append(ref)
@@ -728,6 +776,132 @@ class TaskHistory(RepresentationMixin):
728
776
 
729
777
  return nb
730
778
 
779
+ def offload_files_content(self):
780
+ """
781
+ Offload large file content from scenarios in interview exceptions.
782
+
783
+ This method iterates over all the interview exceptions and calls the offload method
784
+ for any scenario components in the invigilator. This significantly reduces memory usage
785
+ by replacing base64-encoded content with a placeholder string, while preserving the
786
+ structure of the scenarios.
787
+
788
+ Returns:
789
+ self: Returns the TaskHistory instance for method chaining
790
+
791
+ This is particularly useful for TaskHistory instances containing interviews with
792
+ large file content, such as videos, images, or other binary data.
793
+ """
794
+ for interview in self.total_interviews:
795
+ if not hasattr(interview, "exceptions") or not interview.exceptions:
796
+ continue
797
+
798
+ for question_name, exceptions in interview.exceptions.items():
799
+ for exception in exceptions:
800
+ # Check if exception has an invigilator with scenario
801
+ if hasattr(exception, "invigilator") and exception.invigilator:
802
+ if (
803
+ hasattr(exception.invigilator, "scenario")
804
+ and exception.invigilator.scenario
805
+ ):
806
+ # Call the offload method on the scenario
807
+ if hasattr(exception.invigilator.scenario, "offload"):
808
+ try:
809
+ # Replace the original scenario with the offloaded version
810
+ exception.invigilator.scenario = (
811
+ exception.invigilator.scenario.offload()
812
+ )
813
+ except Exception as e:
814
+ # Silently continue if offloading fails for any reason
815
+ pass
816
+
817
+ return self
818
+
819
+ def deduplicate_and_clean_interviews(self):
820
+ """
821
+ Deduplicates exception entries in this task history to reduce memory usage.
822
+
823
+ This method removes duplicate error messages across interviews while preserving
824
+ the first occurrence of each unique error. This significantly reduces the size
825
+ of serialized task history data, especially for jobs with many similar errors.
826
+
827
+ Returns:
828
+ self: Returns the TaskHistory instance for method chaining.
829
+ """
830
+ seen = set()
831
+ cleaned_interviews = []
832
+
833
+ for interview in self.total_interviews:
834
+ # Skip if interview has no exceptions
835
+ if not hasattr(interview, "exceptions") or not interview.exceptions:
836
+ continue
837
+
838
+ keep_interview = False
839
+ questions_to_modify = {}
840
+ questions_to_remove = []
841
+
842
+ # First pass: Collect all modifications without changing the dictionary
843
+ if hasattr(interview.exceptions, "items"):
844
+ for question_name, exceptions in list(interview.exceptions.items()):
845
+ filtered_exceptions = []
846
+
847
+ for exception in exceptions:
848
+ # Get the exception message (may require different access based on structure)
849
+ if hasattr(exception, "exception") and hasattr(
850
+ exception.exception, "args"
851
+ ):
852
+ message = (
853
+ str(exception.exception.args[0])
854
+ if exception.exception.args
855
+ else ""
856
+ )
857
+ else:
858
+ message = str(exception)
859
+
860
+ # Create a unique key for this exception
861
+ key = (question_name, message)
862
+
863
+ # Only keep exceptions we haven't seen before
864
+ if key not in seen:
865
+ seen.add(key)
866
+ filtered_exceptions.append(exception)
867
+
868
+ # Track what should happen to this question's exceptions
869
+ if filtered_exceptions:
870
+ keep_interview = True
871
+ questions_to_modify[question_name] = filtered_exceptions
872
+ else:
873
+ questions_to_remove.append(question_name)
874
+
875
+ # Second pass: Apply all modifications safely
876
+ if hasattr(interview.exceptions, "items"):
877
+ # Add/replace filtered exceptions
878
+ for question_name, filtered_exceptions in questions_to_modify.items():
879
+ interview.exceptions[question_name] = filtered_exceptions
880
+
881
+ # Remove questions with all duplicate exceptions
882
+ for question_name in questions_to_remove:
883
+ if hasattr(interview.exceptions, "pop"):
884
+ interview.exceptions.pop(question_name, None)
885
+ elif (
886
+ hasattr(interview.exceptions, "__delitem__")
887
+ and question_name in interview.exceptions
888
+ ):
889
+ del interview.exceptions[question_name]
890
+
891
+ # Only keep the interview if it still has exceptions after filtering
892
+ if keep_interview:
893
+ cleaned_interviews.append(interview)
894
+
895
+ # Replace the total_interviews with our cleaned list
896
+ self.total_interviews = cleaned_interviews
897
+
898
+ # Rebuild the _interviews dictionary
899
+ self._interviews = {
900
+ index: interview for index, interview in enumerate(self.total_interviews)
901
+ }
902
+
903
+ return self
904
+
731
905
 
732
906
  if __name__ == "__main__":
733
907
  import doctest
@@ -0,0 +1,194 @@
1
+ import asyncio
2
+ import aiohttp
3
+ import time
4
+ import re
5
+ from typing import List
6
+
7
+ def clean_text(text):
8
+ """Clean text by jinja2 braces
9
+ If the text contains {{ or }} then replace it with the empty string
10
+ """
11
+ return re.sub(r'({{.*?}})', '', text)
12
+
13
+
14
+ async def fetch_wikipedia_content_async(search_terms: List[str], concurrency_limit=20):
15
+ """
16
+ Asynchronously fetch Wikipedia content for multiple search terms.
17
+
18
+ Args:
19
+ search_terms (list): List of search terms to look up on Wikipedia
20
+ concurrency_limit (int): Maximum number of concurrent requests
21
+
22
+ Returns:
23
+ list: List of dictionaries containing search results
24
+ """
25
+ async def fetch_wiki_search(session, search_term):
26
+ """Search for a Wikipedia page"""
27
+ search_url = "https://en.wikipedia.org/w/api.php"
28
+ search_params = {
29
+ "action": "query",
30
+ "format": "json",
31
+ "list": "search",
32
+ "srsearch": search_term,
33
+ "utf8": "1"
34
+ }
35
+
36
+ async with session.get(search_url, params=search_params) as response:
37
+ search_data = await response.json()
38
+
39
+ if "query" in search_data and search_data["query"]["search"]:
40
+ return {
41
+ "search_term": search_term,
42
+ "title": search_data["query"]["search"][0]["title"],
43
+ "found": True
44
+ }
45
+ else:
46
+ return {
47
+ "search_term": search_term,
48
+ "found": False
49
+ }
50
+
51
+ async def fetch_wiki_content(session, page_title):
52
+ """Fetch content of a Wikipedia page"""
53
+ content_url = "https://en.wikipedia.org/w/api.php"
54
+ content_params = {
55
+ "action": "query",
56
+ "format": "json",
57
+ "titles": page_title,
58
+ "prop": "extracts|pageimages|categories|links|info",
59
+ "explaintext": "1",
60
+ "exsectionformat": "plain",
61
+ "inprop": "url",
62
+ "pithumbsize": "100", # Get a small thumbnail if available
63
+ "cllimit": "20", # Limit to 20 categories
64
+ "plimit": "20", # Limit to 20 links
65
+ "redirects": "1" # Follow redirects
66
+ }
67
+
68
+ async with session.get(content_url, params=content_params) as response:
69
+ content_data = await response.json()
70
+ page_id = list(content_data["query"]["pages"].keys())[0]
71
+
72
+ if page_id != "-1": # -1 indicates page not found
73
+ page_data = content_data["query"]["pages"][page_id]
74
+
75
+ result = {
76
+ "title": page_data.get("title", ""),
77
+ "page_id": page_id,
78
+ "content": clean_text(page_data.get("extract", "")),
79
+ "url": page_data.get("fullurl", ""),
80
+ "last_modified": page_data.get("touched", "")
81
+ }
82
+
83
+ # Add categories if available
84
+ if "categories" in page_data:
85
+ result["categories"] = [cat["title"].replace("Category:", "")
86
+ for cat in page_data["categories"]]
87
+
88
+ # Add links if available
89
+ if "links" in page_data:
90
+ result["links"] = [link["title"] for link in page_data["links"]]
91
+
92
+ # Add thumbnail if available
93
+ if "thumbnail" in page_data:
94
+ result["thumbnail"] = page_data["thumbnail"].get("source", "")
95
+
96
+ return result
97
+ else:
98
+ return {
99
+ "title": page_title,
100
+ "error": "Page not found"
101
+ }
102
+
103
+ async def process_wiki_item(session, search_term):
104
+ """Process a single search term to get Wikipedia content"""
105
+ search_result = await fetch_wiki_search(session, search_term)
106
+
107
+ if search_result["found"]:
108
+ content_result = await fetch_wiki_content(session, search_result["title"])
109
+
110
+ # Create a complete result
111
+ result = {
112
+ "search_term": search_term,
113
+ "status": "Success",
114
+ **content_result
115
+ }
116
+
117
+ return result
118
+ else:
119
+ return {
120
+ "search_term": search_term,
121
+ "status": "Not found"
122
+ }
123
+
124
+ start_time = time.time()
125
+
126
+ # Create a ClientSession that will be used for all requests
127
+ async with aiohttp.ClientSession(
128
+ headers={"User-Agent": "WikiBatchFetcher/1.0 (your@email.com)"}
129
+ ) as session:
130
+ # Create semaphore to limit concurrency
131
+ semaphore = asyncio.Semaphore(concurrency_limit)
132
+
133
+ async def bounded_process(search_term):
134
+ async with semaphore:
135
+ return await process_wiki_item(session, search_term)
136
+
137
+ # Create tasks for all search terms
138
+ tasks = [bounded_process(term) for term in search_terms]
139
+
140
+ # Wait for all tasks to complete
141
+ results = await asyncio.gather(*tasks)
142
+
143
+ end_time = time.time()
144
+
145
+ # Log summary statistics
146
+ success_count = sum(1 for r in results if r.get("status") == "Success")
147
+ #print(f"Processed {len(search_terms)} search terms in {end_time - start_time:.2f} seconds")
148
+ #print(f"Successfully retrieved {success_count} pages")
149
+
150
+ return results
151
+
152
+ def fetch_wikipedia_content(search_terms, concurrency_limit=20):
153
+ """
154
+ Synchronous wrapper for the async function to fetch Wikipedia content
155
+
156
+ Args:
157
+ search_terms (list): List of search terms to look up on Wikipedia
158
+ concurrency_limit (int): Maximum number of concurrent requests
159
+
160
+ Returns:
161
+ list: List of dictionaries containing search results
162
+ """
163
+ return asyncio.run(
164
+ fetch_wikipedia_content_async(
165
+ search_terms=search_terms,
166
+ concurrency_limit=concurrency_limit
167
+ )
168
+ )
169
+
170
+ # Example usage
171
+ if __name__ == "__main__":
172
+ # Example search terms
173
+ search_terms = [
174
+ "Tommy Tuberville",
175
+ "Albert Einstein",
176
+ "Marie Curie"
177
+ ]
178
+
179
+ # Call the function
180
+ results = fetch_wikipedia_content(
181
+ search_terms=search_terms,
182
+ concurrency_limit=20
183
+ )
184
+
185
+ # Print a sample of the results
186
+ for result in results:
187
+ print(f"\nSearch term: {result['search_term']}")
188
+ print(f"Status: {result['status']}")
189
+ if result['status'] == 'Success':
190
+ print(f"Title: {result['title']}")
191
+ print(f"URL: {result['url']}")
192
+ print(f"Content length: {len(result['content'])} characters")
193
+ if 'categories' in result:
194
+ print(f"Categories: {', '.join(result['categories'][:3])}...")
@@ -1,18 +1,19 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edsl
3
- Version: 0.1.58
3
+ Version: 0.1.59
4
4
  Summary: Create and analyze LLM-based surveys
5
5
  Home-page: https://www.expectedparrot.com/
6
6
  License: MIT
7
7
  Keywords: LLM,social science,surveys,user research
8
8
  Author: John Horton
9
9
  Author-email: info@expectedparrot.com
10
- Requires-Python: >=3.9.1,<3.13
10
+ Requires-Python: >=3.9.1,<3.14
11
11
  Classifier: License :: OSI Approved :: MIT License
12
12
  Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.10
14
14
  Classifier: Programming Language :: Python :: 3.11
15
15
  Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
16
17
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
17
18
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
18
19
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
@@ -249,5 +250,5 @@ Choose whether to run surveys on your own computer or at the Expected Parrot ser
249
250
  Easily share workflows and projects privately or publicly at Coop: an integrated platform for AI-based research. Your account comes with free credits for running surveys, and lets you securely share keys, track expenses and usage for your team.
250
251
 
251
252
  **Built-in tools for analyis**:
252
- Analyze results as specified datasets from your account or workspace. Easily import data to use with your surveys and export results..
253
+ Analyze results as specified datasets from your account or workspace. Easily import data to use with your surveys and export results.
253
254
 
@@ -1,9 +1,9 @@
1
1
  edsl/__init__.py,sha256=EkpMsEKqKRbN9Qqcn_y8CjX8OjlWFyhxslLrt3SJY0Q,4827
2
2
  edsl/__init__original.py,sha256=PzMzANf98PrSleSThXT4anNkeVqZMdw0tfFonzsoiGk,4446
3
- edsl/__version__.py,sha256=ujgZXX_cw13M2UkyXWVg5j1fgdE25Qb3rUzLZVokSKg,23
3
+ edsl/__version__.py,sha256=6ejKyHgulDwYDrT6JBlbHrh83UmxgavrhSuOolniIfI,23
4
4
  edsl/agents/__init__.py,sha256=AyhfXjygRHT1Pd9w16lcu5Bu0jnBmMPz86aKP1uRL3Y,93
5
- edsl/agents/agent.py,sha256=J0y8dH8tWXffiAVhyPEWJ4xmOKdi-XtSrSlMJ08fd58,55606
6
- edsl/agents/agent_list.py,sha256=-bm8jozPPIHJAqb-1nt9m3TZGw5-tgg4LAjz5Mpj0AE,23071
5
+ edsl/agents/agent.py,sha256=omq3lnEujOObKuDyr0seaTiRL7SbJxMjF6bZXqiTt7c,56296
6
+ edsl/agents/agent_list.py,sha256=k29SMOP2trdYWJs5-tPIfpme97fcnanL1lDhhJK3zfg,24249
7
7
  edsl/agents/descriptors.py,sha256=TfFQWJqhqTWyH89DkNmK6qtH3xV2fUyW9FbI5KnZXv0,4592
8
8
  edsl/agents/exceptions.py,sha256=7KMAtAHKqlkVkd_iVZC_mWXQnzDPV0V_n2iXaGAQgzc,5661
9
9
  edsl/base/__init__.py,sha256=h119NxrAJOV92jnX7ussXNjKFXqzySVGOjMG3G7Zkzc,992
@@ -40,7 +40,7 @@ edsl/conversation/exceptions.py,sha256=DoUCg-ymqGOjOl0cpGT8-sNRVsr3SEwdxGAKtdeZ2
40
40
  edsl/conversation/mug_negotiation.py,sha256=do3PTykM6A2cDGOcsohlevRgLpCICoPx8B0WIYe6hy8,2518
41
41
  edsl/conversation/next_speaker_utilities.py,sha256=bqr5JglCd6bdLc9IZ5zGOAsmN2F4ERiubSMYvZIG7qk,3629
42
42
  edsl/coop/__init__.py,sha256=DU2w1Nu8q6tMAa3xoPC722RrvGhmB_UgUUBJDUywsKY,1542
43
- edsl/coop/coop.py,sha256=NVcteUNmd-1k-MbSzplJnMzFHmFhqr_tjAIvdq2fhLI,71303
43
+ edsl/coop/coop.py,sha256=YfV-jVUlM9Jw2s5x_4uN8RPUEDW3GDoqtYrduPx_ABc,74929
44
44
  edsl/coop/coop_functions.py,sha256=d31kddfj9MVZaMhqwUvkSIBwrdCTQglIvFWVfUr4NuE,688
45
45
  edsl/coop/coop_jobs_objects.py,sha256=_OFPVLKswXY9mKl9b3Y7gxlUhaMZ7GULx5OqyANpecU,1701
46
46
  edsl/coop/coop_objects.py,sha256=_cEspdAxh7BT672poxb0HsjU-QZ4Kthg-tKDvZ6I_v0,859
@@ -51,8 +51,8 @@ edsl/coop/price_fetcher.py,sha256=uvEPgKaSRsFq-ouRl5W9aksawUkJg9Lo7ucSePecwa4,47
51
51
  edsl/coop/utils.py,sha256=DON2ns5nWlUqqvlNVUsdgiPlz-6oEqFVOmjhnOwHQBs,8174
52
52
  edsl/data_transfer_models.py,sha256=pPaKsbo9pgNcBB9kX-U2O_dUtNkd0Xm4JNmv26jrbhI,265
53
53
  edsl/dataset/__init__.py,sha256=RIzfFIytKJfniKZ0VThMk8Z2fjejx91t9PZBct78xXw,422
54
- edsl/dataset/dataset.py,sha256=kfjfF4B-SlTeBL2FHDiLdwTZOm8RmWqTUOTQStNiOqk,39563
55
- edsl/dataset/dataset_operations_mixin.py,sha256=dVjTLHjBW9oQ55k3EZnhG89JHPxxYG-nfk0lmPqkuMQ,58212
54
+ edsl/dataset/dataset.py,sha256=o1icaFSE2ipCj7FDqhXkPb-E42wBzn74hLD7QXg0qaE,42277
55
+ edsl/dataset/dataset_operations_mixin.py,sha256=SDGqQRg0Zdy-VMHDF1z4bChCkZ6t5iT-tP2zydAdyYs,59344
56
56
  edsl/dataset/dataset_tree.py,sha256=mKLQhwo-gxDyJCwCH3gj6Os0Jk2JqfWd_PvUyuWqM6s,14268
57
57
  edsl/dataset/display/CSSParameterizer.py,sha256=vI3VTgTihJeCYGfmGp7fOhTitHZ17jrDGbq46Sa2rd8,3677
58
58
  edsl/dataset/display/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -93,7 +93,7 @@ edsl/inference_services/services/mistral_ai_service.py,sha256=tvwIeqhwzT6kPjrUo_
93
93
  edsl/inference_services/services/ollama_service.py,sha256=quSKlgD0bHG9mO_s9verGePfqQi_rZWovHEQ6dy-Fe0,303
94
94
  edsl/inference_services/services/open_ai_service.py,sha256=WFcl9g7Y28hckdiD_bPxRL_yJqz9ukERL3h_znh6b80,8682
95
95
  edsl/inference_services/services/perplexity_service.py,sha256=7bt5Mb6Dxkb7UOljNdTBpZuT_8ri4i6Sk_h5g8paKu4,5994
96
- edsl/inference_services/services/test_service.py,sha256=rJlXGyMbHcYpws3zH23taoA2Pq5sYiYpc52jYNoIfe0,7393
96
+ edsl/inference_services/services/test_service.py,sha256=JUK2bch1uu5XefMhNnuAXCbTqgiMqQRAIN8xYCMNe1E,7394
97
97
  edsl/inference_services/services/together_ai_service.py,sha256=biUYs07jsrIHp19O81o0nJCwYdSWudMEXdGtmA1-y60,6151
98
98
  edsl/inference_services/services/xai_service.py,sha256=hJbXF26DuFTZdy0lYT1wo3yyuWDcwcXA6EiGYUahK1w,280
99
99
  edsl/inference_services/write_available.py,sha256=9L8chJb8iafHfwRBfqZKjMjkSBRWUa5gEe7F0mxsZu0,261
@@ -106,7 +106,7 @@ edsl/instructions/instruction_handler.py,sha256=MXy0LSyAUE5H2G8Pdhs-WerZM8VWGqNR
106
106
  edsl/interviews/ReportErrors.py,sha256=5NC6fFGaVe6Qk4gnFd7fUFRsw9MKb7g4MFOr-EblS0o,1728
107
107
  edsl/interviews/__init__.py,sha256=BC6NBomroZEc8uwOeZBMtVuXwAVQzTzm7kkgDBqEBic,328
108
108
  edsl/interviews/answering_function.py,sha256=zmUMGP1xSpDm49_dqj39g8BoGGy0OmhlcUrJQvUyio8,13695
109
- edsl/interviews/exception_tracking.py,sha256=ayM7Ntoe7_FQbcsJICQ-fWiqo71hvu-nj62DLct4rfU,11223
109
+ edsl/interviews/exception_tracking.py,sha256=2DTpDHGq_7ItZ7O3AUtKM8Wmox2EEqZi28xtCYtYHRU,13206
110
110
  edsl/interviews/exceptions.py,sha256=qID-2HnSHJt5DyxBQd4698GZfTEu8rwk_VbIrBHcIRc,2626
111
111
  edsl/interviews/interview.py,sha256=LyLY6kbjeUih_DREgIU38AIkrSWsKqSSgoVoLiUMlCE,26450
112
112
  edsl/interviews/interview_status_dictionary.py,sha256=0ZvXLusfOA8xD_Fco4PjEBGwmR2sizHOGijTQI8RrI8,3031
@@ -118,8 +118,8 @@ edsl/interviews/statistics.py,sha256=lZCtq79QrDKG3jXao_OWuBRhnly9VyuhM6IdTJaYqPg
118
118
  edsl/invigilators/__init__.py,sha256=fKbZ7p9-kMelpvET3Ku2Owu-tL_apC-8gi9JychpMBY,1843
119
119
  edsl/invigilators/exceptions.py,sha256=ejoF-Gt-YcnW1yHyfpJ3jZm8AC_zD0GCYafRO2LlAMQ,2767
120
120
  edsl/invigilators/invigilator_base.py,sha256=DgrXTK4AAxXr4wg2pzc0p1aGPPf1UUt01C-JW1UBTvo,20099
121
- edsl/invigilators/invigilators.py,sha256=84dtOXJJX-oEiKDRAfir6iEKb7ovfB2FUWBKjykeUiE,23787
122
- edsl/invigilators/prompt_constructor.py,sha256=THHGcZPI-QUOH8Z9cQEzH7bZEoo0V_Nc_Phlhc9AzL0,19115
121
+ edsl/invigilators/invigilators.py,sha256=8RyV8_8wc3tLMjUHJhyJLDq7CrFMo4X9gEVQz-pOks4,24025
122
+ edsl/invigilators/prompt_constructor.py,sha256=_Bh0MHWcNk0friHpDJ8F6L6JAZKf95-06lZB8U0caUQ,25266
123
123
  edsl/invigilators/prompt_helpers.py,sha256=LuMZFZkInPY8M7Rw9fG9rpJIcT89tr2_Iq10ZHH_Y4A,5409
124
124
  edsl/invigilators/question_instructions_prompt_builder.py,sha256=E5zpwctpt_5JjONkZRcMwB0MACAzDvvnzUhmuWTnjd0,9684
125
125
  edsl/invigilators/question_option_processor.py,sha256=TRJgeFUH4m2EUlkjWkXnMWiE_CXQjO0gHyPOd_qjbec,9504
@@ -131,17 +131,17 @@ edsl/jobs/data_structures.py,sha256=i-XXq2zul1K1aOZDZXbPIO8l-0bJLqDL2t7pxITXbks,
131
131
  edsl/jobs/decorators.py,sha256=0Eot9pFPsWmQIJAafNd0f5hdb9RUAFp_hGMmSUTJ_C8,3272
132
132
  edsl/jobs/exceptions.py,sha256=5lktTya2VgiBR5Bd977tG2xHdrMjDqhPhQO17O6jIdc,7220
133
133
  edsl/jobs/fetch_invigilator.py,sha256=nzXAIulvOvuDpRDEN5TDNmEfikUEwrnS_XCtnYG2uPQ,2795
134
- edsl/jobs/html_table_job_logger.py,sha256=rtVnfP9aBG6_S-PdkUI3K4DZN7sS-paAj-smgyknDuE,33729
134
+ edsl/jobs/html_table_job_logger.py,sha256=2ErAIi_Dgv_Y3l-AZ2bPUJO_X8hSrPfeFT9lEjt8X4g,34762
135
135
  edsl/jobs/jobs.py,sha256=WL3ODJ4HBElnw2XVaPXqfvHzyTsEe0XeUghOZOyI0FA,42334
136
136
  edsl/jobs/jobs_checks.py,sha256=bfPJ3hQ4qvRBhyte4g-4J8zExJxJr3nlLHmtVmFPJcQ,5390
137
137
  edsl/jobs/jobs_component_constructor.py,sha256=9956UURv3eo-cURNPd4EV8wAQsY-AlEtQRmBu1nCOH8,6982
138
138
  edsl/jobs/jobs_interview_constructor.py,sha256=8nIhhwBQWH_aZ9ZWjvRgOL0y2y6juRTb3pVngQ9Cs8g,2017
139
- edsl/jobs/jobs_pricing_estimation.py,sha256=vCrqAMdzocKcJ3d0sWYStajY2G4YwGD26PAQZdS_Stk,14085
140
- edsl/jobs/jobs_remote_inference_logger.py,sha256=gHVxumpFQ2NxbLkd1fdkiZkOcMNoCdHqeQHxFdXOv9s,10039
139
+ edsl/jobs/jobs_pricing_estimation.py,sha256=OsCQHR-HuATPQDyND00HJ47CWqcAFNuhOb0KbbceoaU,14349
140
+ edsl/jobs/jobs_remote_inference_logger.py,sha256=4I3DjIzxfWHjWBr7o_JPhj9f8M4LuuPisCtQxjSFkxA,10132
141
141
  edsl/jobs/jobs_runner_status.py,sha256=gW8EA-BAKpBvahqRipzomALEAQizd24aRW8G2y7faLQ,11905
142
142
  edsl/jobs/jobs_status_enums.py,sha256=8Kgtr-ffcGGniQ2x5gCOqwURb_HaBWmYcWbUB_KTCY0,214
143
143
  edsl/jobs/progress_bar_manager.py,sha256=d8wuZf7SHq3LCA36JIv1sfYymyHFOUsYRSRlRpR6K04,2832
144
- edsl/jobs/remote_inference.py,sha256=d3Bxg4bJzZnQ2vVlZdMgMM8vMXkWh5odgH4svpfyb_Q,21308
144
+ edsl/jobs/remote_inference.py,sha256=iO_ObqHL0fkn9-f-oPCEf3UqfX9BUlVhjycjy_i4LHM,22616
145
145
  edsl/jobs/results_exceptions_handler.py,sha256=VCtnd60xwdFznzGhtXPbxLmyVf3kIjR2419LUJdFjEQ,3053
146
146
  edsl/key_management/__init__.py,sha256=JiOJ71Ly9aw-tVYbWZu-qRjsW4QETYMQ9IJjsKgW1DQ,1274
147
147
  edsl/key_management/exceptions.py,sha256=dDtoDh1UL52BUBrAlCIc_McgtZCAQkUx6onoSz26qeM,2158
@@ -151,7 +151,7 @@ edsl/key_management/key_lookup_collection.py,sha256=b1STYU4FIqgCtCf90bRZh6IXf8kc
151
151
  edsl/key_management/models.py,sha256=z9TimNMnz47mnITM5SlJy2m2sk1aKKtt0ybV89rsaiY,6703
152
152
  edsl/language_models/__init__.py,sha256=WtefJs6XOCn5RSz22PgoAi3eTEr1NzGtnnBpDIie2mg,240
153
153
  edsl/language_models/exceptions.py,sha256=P9dMA8XfK_qcuXNJZ-Xsb_Ny-12Ldu3fPC133RB40Ek,13728
154
- edsl/language_models/language_model.py,sha256=u1sclHfmIfjXlgW6IGpr-nK4V-HJRIrpBmPiNAqbZOo,44675
154
+ edsl/language_models/language_model.py,sha256=gN3qW1NUK4kPl_CfgMKUd8ORdSB0iEZC0miuZDsCQUw,46462
155
155
  edsl/language_models/model.py,sha256=oYZsfgvko_EH4EWT9XZPEgLcs9KA36SGEAKZwYRFjv8,12013
156
156
  edsl/language_models/model_list.py,sha256=Eb62xQdrlayqWYyJVgYxheMiNi14e1U9b_12qYzy1ws,4522
157
157
  edsl/language_models/price_manager.py,sha256=74XEkoVdQv06w7gMFZmXeeXGW6om4_ISr-qFnmX4lFE,10711
@@ -178,7 +178,7 @@ edsl/plugins/plugin_manager.py,sha256=ifuJLgcySmLvGOc8ka8tSj-3d6ju0NknEK22pLF1L8
178
178
  edsl/plugins/plugins_registry.py,sha256=stAaq6vkuurHc3ViHrLj5g2VomMpsLD9ufa-k-HHfgk,5165
179
179
  edsl/prompts/__init__.py,sha256=4UREcqKC6SIfYykwZbaCeXI5hEil0u2x5GQKasn_NLU,653
180
180
  edsl/prompts/exceptions.py,sha256=AcQCy8JGmS8ODCvRtu4aCH14OEI-oYxF0tX-ZAZ3Puk,4460
181
- edsl/prompts/prompt.py,sha256=eHb7zWhkO7J5PwnZITaS4r1lbIWLBiJ8s3Z5aRyUC8M,14201
181
+ edsl/prompts/prompt.py,sha256=mFCOAEHHKJ5RGMRtdkTlNMmRmsem-XligJjRVlO-PbY,14221
182
182
  edsl/questions/ExceptionExplainer.py,sha256=BgM80FRPJjS_TrY6XaVmlT666MzY9DEagviGQj9-WEQ,2868
183
183
  edsl/questions/HTMLQuestion.py,sha256=lx3Sysm6fMZmFc9hifnkGslt7ZBpDEvziM9-IJFMJLU,3238
184
184
  edsl/questions/Quick.py,sha256=HRLT2Lmhd1Gj4ggkrpCMYhzeWsRwlQaigu2EzdiXb5Q,1717
@@ -210,7 +210,7 @@ edsl/questions/question_free_text.py,sha256=Oaw7C5BCclCiaWJlWHQJFEPppKxT7zWBFyIb
210
210
  edsl/questions/question_functional.py,sha256=iwFlJmXBoFDu5D4tZ4Ci_yhfQo8_tB9C3W5I2p7KipA,9524
211
211
  edsl/questions/question_likert_five.py,sha256=MG1R7I7KZjAff7qhMQ0b462GJRC6MKgUZBP4wiqqmio,6547
212
212
  edsl/questions/question_linear_scale.py,sha256=OSGV6vwoAgDKoZhudqKiUPpJY8iMpHWNkCr0KlTZrpc,3350
213
- edsl/questions/question_list.py,sha256=07Imgbji6RnNnh_UnhdOFGejon72StGP9ntXkV977oo,17849
213
+ edsl/questions/question_list.py,sha256=CkmR3LntXyAiQUrVZLZTlniK5D8WMTDcQqwMWJwL9_A,20697
214
214
  edsl/questions/question_matrix.py,sha256=Okg3sRboG4C1ArTSgUXUWlJJzWqsUimgB1lYtI9Hq8o,37397
215
215
  edsl/questions/question_multiple_choice.py,sha256=uTWZ0FGE8czIxmiZ_6mvc8KR5efpatZo_egid1WrHgc,23679
216
216
  edsl/questions/question_multiple_choice_with_other.py,sha256=J0_3V5SfetQzqqVMgTIZ5TUwiY4X-bMCogSqquG0tzQ,23624
@@ -279,7 +279,7 @@ edsl/results/__init__.py,sha256=RKbHY0g6s_k42VcdmTOZ2yB_nltiJnnbeQAkUY5WD9o,129
279
279
  edsl/results/exceptions.py,sha256=u-TQsazt_qj-G4eJKBnj0UtpnIiw6A2GcCLJ2wTYE_g,6536
280
280
  edsl/results/report.py,sha256=oHjMY981Gn8estqvoTk5SPiuEOIM0IR_QPBrRLdk5pM,7481
281
281
  edsl/results/result.py,sha256=5cT7ikHDoNASGINRLDRCpMokusz0Plx5iq7LJ9pgK5I,29723
282
- edsl/results/results.py,sha256=7vC_6MKCPcIPO9GxnT9POJElNF-r7ywEnVWuWiSI6L0,84727
282
+ edsl/results/results.py,sha256=BOy_NfRAWu9Q_JeuMtfG04oQhE7hMuiJ-WAH6_ov6Vk,84973
283
283
  edsl/results/results_selector.py,sha256=4_XMS2Fb-3rcXEPUYaBRw52r1i66jttjttqNFe6PRc4,18050
284
284
  edsl/scenarios/DocxScenario.py,sha256=ul3nkX826m_T6LFptswqtnH5czP_yxMlLWgbTmFIZI4,482
285
285
  edsl/scenarios/PdfExtractor.py,sha256=6nPZ6v9x2RrU42EkqlEcW3MS-WIQpGfwg4--6WvEC8I,1972
@@ -289,7 +289,7 @@ edsl/scenarios/directory_scanner.py,sha256=xv-3HHRPsyGa8m6mHpqLjK-UBC-nhG9gz3VC5
289
289
  edsl/scenarios/document_chunker.py,sha256=EpB0V0oxLzpKntl00Qa3VZNPS7sg9aXdYyqKxhFFzTM,7680
290
290
  edsl/scenarios/exceptions.py,sha256=FeORBm90UthKHDp7cE8I7KJgyA3-pFKNpoivZRr8ifc,10636
291
291
  edsl/scenarios/file_methods.py,sha256=LkN7mZsadRaiNhvKPP_jY7OhUMEsfhEEFY-hpnwdplM,2794
292
- edsl/scenarios/file_store.py,sha256=tUDYeiCuV_C6XBYiBTAYGmUz7INBJ3n4_5xky_Q7oQA,33159
292
+ edsl/scenarios/file_store.py,sha256=YmcI9DcHwbTmsYk5RARpAHRuwjfM2RAL3kVjh5WnCn0,32910
293
293
  edsl/scenarios/handlers/__init__.py,sha256=_-A6vXzQPKga7fDyteDt1QPA6lDwmgERJKG8SrdhYxQ,965
294
294
  edsl/scenarios/handlers/csv_file_store.py,sha256=kXOms0ph5JJj6jSbpfQ-SZjuT4vvSRhq5AGpv1L4TPQ,1369
295
295
  edsl/scenarios/handlers/docx_file_store.py,sha256=KSKAAUIWF2K5xr92nx7UGQ9djgtDX4ke-Eyik8QAdlQ,2155
@@ -307,9 +307,9 @@ edsl/scenarios/handlers/sql_file_store.py,sha256=wa_Qw1-bk-tHhtQrp1IAxSAROygEQ5F
307
307
  edsl/scenarios/handlers/sqlite_file_store.py,sha256=rwsfxD5G_XNEa-aRCx6A83lW0i2OiS51EzYsJeTE7ps,4936
308
308
  edsl/scenarios/handlers/txt_file_store.py,sha256=oGMqm2X_dWTt0W2e2zDung2i_A_z2mMmm4rrQImnVtU,980
309
309
  edsl/scenarios/handlers/webm_file_store.py,sha256=UG3sPwsxbZAjM1H9rbpdkvXMrS3iRbaaN-4VNGh3JX8,3659
310
- edsl/scenarios/scenario.py,sha256=NAm-VCqM8x0OC6idOEHupzrqDoY7nr1E3448Q65ECaA,37384
310
+ edsl/scenarios/scenario.py,sha256=3LQhJ8QSVaatuV2DZOJwJDRgrwyx2zmOE0B-7AIVTtI,39184
311
311
  edsl/scenarios/scenario_join.py,sha256=1r_czZctN7JKbw38bQolKdz0kBaMqhWzo8IsxzHK1TY,5409
312
- edsl/scenarios/scenario_list.py,sha256=XWtro8XODqA7QmWNcDb6IE-4n2dhMEt_MiOREpD-fDE,86817
312
+ edsl/scenarios/scenario_list.py,sha256=GfUvYHgSMyvBbYJZ1f7YvodcQ9DhLyrR3DrKB4R7nsI,87652
313
313
  edsl/scenarios/scenario_list_gc_test.py,sha256=VaZBg_GjfSaM92Gj3eiSt3aQ_rECDfD339ZCTqryfdc,4676
314
314
  edsl/scenarios/scenario_list_memory_test.py,sha256=l_PeTJkh0MYQoRLIiFOI8hmzEyjf86_PG7UvU-2-l_o,7138
315
315
  edsl/scenarios/scenario_list_pdf_tools.py,sha256=sehQro5PzJ7Y4Ck9VJ8HTxKN8HSbk3aDipVYuxaJbdI,7686
@@ -333,7 +333,7 @@ edsl/surveys/rules/__init__.py,sha256=yXrL1uzhv1PdndhI4ArR5-QyMy18Q1Unv3AXpjswHj
333
333
  edsl/surveys/rules/rule.py,sha256=S9XnZNSSHMK8E2HZ4w0imJjCW8RpoD3DZ1p1vSKDp40,15130
334
334
  edsl/surveys/rules/rule_collection.py,sha256=KK3xyklLYyQL5ubFFX_UWXUFM0rLcZgv8L2ofZBBjYo,14140
335
335
  edsl/surveys/rules/rule_manager.py,sha256=SD3wNFlEzmUBzpJsecrup-BugKU2dF5E4XWYyKd-EXg,6332
336
- edsl/surveys/survey.py,sha256=Q6fdyhwI64WOOnPHY56sXE7VpXibqwOuUmXUxbyo_g8,72482
336
+ edsl/surveys/survey.py,sha256=zDmpuPVZlRjNYrB0wFf56BjkbrMjdwY5hGYMTjndCYs,72665
337
337
  edsl/surveys/survey_css.py,sha256=-WetQGjvGkp8W4jq94XCHewvzbOLBKPCpsxIjRi2hG8,8789
338
338
  edsl/surveys/survey_export.py,sha256=rmlRdLW_KYuzkPxM65NU0DZlihH-67tUoCBc7I-7VxQ,8275
339
339
  edsl/surveys/survey_flow_visualization.py,sha256=aEmmwYeaa2YaTILEwsRANPfmNLut_oCmUd9iHPBtXwA,9550
@@ -342,7 +342,7 @@ edsl/tasks/__init__.py,sha256=24Uw8dEDLoHfyJgNgjHOcJ_dKjjZZz68FH0PUC7M0bE,2000
342
342
  edsl/tasks/exceptions.py,sha256=vi-ns7T8UrdOQD9PBSO-8hYlXgoperykX5c2hrYaNg4,2022
343
343
  edsl/tasks/question_task_creator.py,sha256=ZSht6I3k5JjQaARufj1hdJbvWltwUzx40ikvmAjL0FA,12110
344
344
  edsl/tasks/task_creators.py,sha256=u-CxzB0Qv90PDkfi0bQV3EAT89co9fXIal5JOUPcKls,5616
345
- edsl/tasks/task_history.py,sha256=1Mn4CmpWktsI1R0J1nynEfDdTk7dDufCIJEZCN39xQ0,28538
345
+ edsl/tasks/task_history.py,sha256=YvAM99jnWhQtzrlR4q7UQgxJk6dakbzsria9MHuBPjs,36438
346
346
  edsl/tasks/task_status_enum.py,sha256=cQSJMcswLGdknO7tvNZBZV05T_TZV-MEBY3DxyLzTo0,9032
347
347
  edsl/tasks/task_status_log.py,sha256=dbeZ5LUCJzWzBbMEIRUZKP1hjANJy7enyTiEU7hwS8w,3165
348
348
  edsl/templates/error_reporting/base.html,sha256=BsPp87_XfLJZA4V0oPF8ulmTFyPHgB3KyPEJkgSxsmQ,1299
@@ -381,8 +381,9 @@ edsl/utilities/repair_functions.py,sha256=EXkXsqnmgPqj9b3dff1cZnJyaZw-qEvGENXCRH
381
381
  edsl/utilities/restricted_python.py,sha256=248N2p5EWHDSpcK1G-q7DUoJeWy4sB6aO-RV0-5O7uY,2038
382
382
  edsl/utilities/template_loader.py,sha256=SCAcnTnxNQ67MNSkmfz7F-S_u2peyGn2j1oRIqi1wfg,870
383
383
  edsl/utilities/utilities.py,sha256=irHheAGOnl_6RwI--Hi9StVzvsHcWCqB48PWsWJQYOw,12045
384
- edsl-0.1.58.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
385
- edsl-0.1.58.dist-info/METADATA,sha256=nEQbjRPWHb8aJaKUrfyakIvvXL2qIQyyQsDYa0IToqU,12032
386
- edsl-0.1.58.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
387
- edsl-0.1.58.dist-info/entry_points.txt,sha256=JnG7xqMtHaQu9BU-yPATxdyCeA48XJpuclnWCqMfIMU,38
388
- edsl-0.1.58.dist-info/RECORD,,
384
+ edsl/utilities/wikipedia.py,sha256=I3Imbz3fzbaoA0ZLDsWUO2YpP_ovvaqtu-yd2Ye1BB0,6933
385
+ edsl-0.1.59.dist-info/LICENSE,sha256=_qszBDs8KHShVYcYzdMz3HNMtH-fKN_p5zjoVAVumFc,1111
386
+ edsl-0.1.59.dist-info/METADATA,sha256=FxWojFvdFs_p5nVxCwWquIeheS8yTHhAwXcGECq2ejg,12082
387
+ edsl-0.1.59.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
388
+ edsl-0.1.59.dist-info/entry_points.txt,sha256=JnG7xqMtHaQu9BU-yPATxdyCeA48XJpuclnWCqMfIMU,38
389
+ edsl-0.1.59.dist-info/RECORD,,
File without changes
File without changes