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.
Files changed (76) hide show
  1. edsl/Base.py +18 -18
  2. edsl/__init__.py +24 -24
  3. edsl/__version__.py +1 -1
  4. edsl/agents/Agent.py +41 -77
  5. edsl/agents/AgentList.py +6 -35
  6. edsl/agents/Invigilator.py +1 -19
  7. edsl/agents/InvigilatorBase.py +10 -15
  8. edsl/agents/PromptConstructionMixin.py +100 -342
  9. edsl/agents/descriptors.py +1 -2
  10. edsl/config.py +1 -2
  11. edsl/conjure/InputData.py +8 -39
  12. edsl/coop/coop.py +150 -187
  13. edsl/coop/utils.py +75 -43
  14. edsl/data/Cache.py +5 -19
  15. edsl/data/SQLiteDict.py +3 -11
  16. edsl/jobs/Answers.py +1 -15
  17. edsl/jobs/Jobs.py +46 -90
  18. edsl/jobs/buckets/ModelBuckets.py +2 -4
  19. edsl/jobs/buckets/TokenBucket.py +2 -1
  20. edsl/jobs/interviews/Interview.py +9 -3
  21. edsl/jobs/interviews/InterviewStatusMixin.py +3 -3
  22. edsl/jobs/interviews/InterviewTaskBuildingMixin.py +10 -15
  23. edsl/jobs/runners/JobsRunnerAsyncio.py +25 -21
  24. edsl/jobs/tasks/TaskHistory.py +3 -4
  25. edsl/language_models/LanguageModel.py +11 -5
  26. edsl/language_models/ModelList.py +3 -3
  27. edsl/language_models/repair.py +7 -8
  28. edsl/notebooks/Notebook.py +3 -40
  29. edsl/prompts/Prompt.py +19 -31
  30. edsl/questions/QuestionBase.py +13 -38
  31. edsl/questions/QuestionBudget.py +6 -5
  32. edsl/questions/QuestionCheckBox.py +3 -7
  33. edsl/questions/QuestionExtract.py +3 -5
  34. edsl/questions/QuestionFreeText.py +3 -3
  35. edsl/questions/QuestionFunctional.py +3 -0
  36. edsl/questions/QuestionList.py +4 -3
  37. edsl/questions/QuestionMultipleChoice.py +8 -16
  38. edsl/questions/QuestionNumerical.py +3 -4
  39. edsl/questions/QuestionRank.py +3 -5
  40. edsl/questions/__init__.py +3 -4
  41. edsl/questions/descriptors.py +2 -4
  42. edsl/questions/question_registry.py +31 -20
  43. edsl/questions/settings.py +1 -1
  44. edsl/results/Dataset.py +0 -31
  45. edsl/results/Result.py +74 -22
  46. edsl/results/Results.py +47 -97
  47. edsl/results/ResultsDBMixin.py +3 -7
  48. edsl/results/ResultsExportMixin.py +537 -22
  49. edsl/results/ResultsGGMixin.py +3 -3
  50. edsl/results/ResultsToolsMixin.py +5 -5
  51. edsl/scenarios/Scenario.py +6 -5
  52. edsl/scenarios/ScenarioList.py +11 -34
  53. edsl/scenarios/ScenarioListPdfMixin.py +1 -2
  54. edsl/scenarios/__init__.py +0 -1
  55. edsl/study/ObjectEntry.py +13 -89
  56. edsl/study/ProofOfWork.py +2 -5
  57. edsl/study/SnapShot.py +8 -4
  58. edsl/study/Study.py +14 -21
  59. edsl/study/__init__.py +0 -2
  60. edsl/surveys/MemoryPlan.py +4 -11
  61. edsl/surveys/Survey.py +7 -46
  62. edsl/surveys/SurveyExportMixin.py +2 -4
  63. edsl/surveys/SurveyFlowVisualizationMixin.py +4 -6
  64. edsl/tools/plotting.py +2 -4
  65. edsl/utilities/__init__.py +21 -21
  66. edsl/utilities/interface.py +45 -66
  67. edsl/utilities/utilities.py +13 -11
  68. {edsl-0.1.29.dist-info → edsl-0.1.29.dev1.dist-info}/METADATA +10 -11
  69. {edsl-0.1.29.dist-info → edsl-0.1.29.dev1.dist-info}/RECORD +72 -75
  70. edsl-0.1.29.dev1.dist-info/entry_points.txt +3 -0
  71. edsl/base/Base.py +0 -289
  72. edsl/results/DatasetExportMixin.py +0 -493
  73. edsl/scenarios/FileStore.py +0 -140
  74. edsl/scenarios/ScenarioListExportMixin.py +0 -32
  75. {edsl-0.1.29.dist-info → edsl-0.1.29.dev1.dist-info}/LICENSE +0 -0
  76. {edsl-0.1.29.dist-info → edsl-0.1.29.dev1.dist-info}/WHEEL +0 -0
edsl/Base.py CHANGED
@@ -6,6 +6,9 @@ import io
6
6
  import json
7
7
  from typing import Any, Optional, Union
8
8
  from uuid import UUID
9
+ from IPython.display import display
10
+ from rich.console import Console
11
+ from edsl.utilities import is_notebook
9
12
 
10
13
 
11
14
  class RichPrintingMixin:
@@ -13,8 +16,6 @@ class RichPrintingMixin:
13
16
 
14
17
  def _for_console(self):
15
18
  """Return a string representation of the object for console printing."""
16
- from rich.console import Console
17
-
18
19
  with io.StringIO() as buf:
19
20
  console = Console(file=buf, record=True)
20
21
  table = self.rich_print()
@@ -27,11 +28,7 @@ class RichPrintingMixin:
27
28
 
28
29
  def print(self):
29
30
  """Print the object to the console."""
30
- from edsl.utilities.utilities import is_notebook
31
-
32
31
  if is_notebook():
33
- from IPython.display import display
34
-
35
32
  display(self.rich_print())
36
33
  else:
37
34
  from rich.console import Console
@@ -55,28 +52,31 @@ class PersistenceMixin:
55
52
  return c.create(self, description, visibility)
56
53
 
57
54
  @classmethod
58
- def pull(cls, uuid: Optional[Union[str, UUID]] = None, url: Optional[str] = None):
55
+ def pull(cls, id_or_url: Union[str, UUID], exec_profile=None):
59
56
  """Pull the object from coop."""
60
57
  from edsl.coop import Coop
61
- from edsl.coop.utils import ObjectRegistry
62
58
 
63
- object_type = ObjectRegistry.get_object_type_by_edsl_class(cls)
64
- coop = Coop()
65
- return coop.get(uuid, url, object_type)
59
+ if id_or_url.startswith("http"):
60
+ uuid_value = id_or_url.split("/")[-1]
61
+ else:
62
+ uuid_value = id_or_url
63
+
64
+ c = Coop()
65
+
66
+ return c._get_base(cls, uuid_value, exec_profile=exec_profile)
66
67
 
67
68
  @classmethod
68
- def delete(cls, uuid: Optional[Union[str, UUID]] = None, url: Optional[str] = None):
69
+ def delete(cls, id_or_url: Union[str, UUID]):
69
70
  """Delete the object from coop."""
70
71
  from edsl.coop import Coop
71
72
 
72
- coop = Coop()
73
- return coop.delete(uuid, url)
73
+ c = Coop()
74
+ return c._delete_base(cls, id_or_url)
74
75
 
75
76
  @classmethod
76
77
  def patch(
77
78
  cls,
78
- uuid: Optional[Union[str, UUID]] = None,
79
- url: Optional[str] = None,
79
+ id_or_url: Union[str, UUID],
80
80
  description: Optional[str] = None,
81
81
  value: Optional[Any] = None,
82
82
  visibility: Optional[str] = None,
@@ -89,8 +89,8 @@ class PersistenceMixin:
89
89
  """
90
90
  from edsl.coop import Coop
91
91
 
92
- coop = Coop()
93
- return coop.patch(uuid, url, description, value, visibility)
92
+ c = Coop()
93
+ return c._patch_base(cls, id_or_url, description, value, visibility)
94
94
 
95
95
  @classmethod
96
96
  def search(cls, query):
edsl/__init__.py CHANGED
@@ -1,5 +1,4 @@
1
1
  import os
2
- import time
3
2
 
4
3
  BASE_DIR = os.path.dirname(os.path.abspath(__file__))
5
4
  ROOT_DIR = os.path.dirname(BASE_DIR)
@@ -8,35 +7,36 @@ from edsl.__version__ import __version__
8
7
  from edsl.config import Config, CONFIG
9
8
  from edsl.agents.Agent import Agent
10
9
  from edsl.agents.AgentList import AgentList
11
- from edsl.questions import QuestionBase
12
- from edsl.questions import QuestionMultipleChoice
13
- from edsl.questions import QuestionBudget
14
- from edsl.questions import QuestionCheckBox
15
- from edsl.questions import QuestionExtract
16
- from edsl.questions import QuestionFreeText
17
- from edsl.questions import QuestionFunctional
18
- from edsl.questions import QuestionLikertFive
19
- from edsl.questions import QuestionList
20
- from edsl.questions import QuestionLinearScale
21
- from edsl.questions import QuestionNumerical
22
- from edsl.questions import QuestionRank
23
- from edsl.questions import QuestionTopK
24
- from edsl.questions import QuestionYesNo
25
- from edsl.questions.question_registry import Question
26
- from edsl.scenarios import Scenario
27
- from edsl.scenarios import ScenarioList
28
-
29
- # from edsl.utilities.interface import print_dict_with_rich
10
+ from edsl.questions import (
11
+ QuestionBase,
12
+ QuestionBudget,
13
+ QuestionCheckBox,
14
+ QuestionExtract,
15
+ QuestionFreeText,
16
+ QuestionFunctional,
17
+ QuestionLikertFive,
18
+ QuestionList,
19
+ QuestionLinearScale,
20
+ QuestionMultipleChoice,
21
+ QuestionNumerical,
22
+ QuestionRank,
23
+ QuestionTopK,
24
+ QuestionYesNo,
25
+ )
26
+ from edsl.scenarios.Scenario import Scenario
27
+ from edsl.scenarios.ScenarioList import ScenarioList
28
+ from edsl.utilities.interface import print_dict_with_rich
30
29
  from edsl.surveys.Survey import Survey
31
30
  from edsl.language_models.registry import Model
32
- from edsl.language_models.ModelList import ModelList
31
+ from edsl.questions.question_registry import Question
33
32
  from edsl.results.Results import Results
34
33
  from edsl.data.Cache import Cache
35
34
  from edsl.data.CacheEntry import CacheEntry
36
35
  from edsl.data.CacheHandler import set_session_cache, unset_session_cache
37
36
  from edsl.shared import shared_globals
38
- from edsl.jobs.Jobs import Jobs
39
- from edsl.notebooks.Notebook import Notebook
37
+ from edsl.jobs import Jobs
38
+ from edsl.notebooks import Notebook
40
39
  from edsl.study.Study import Study
41
- from edsl.conjure.Conjure import Conjure
42
40
  from edsl.coop.coop import Coop
41
+ from edsl.conjure.Conjure import Conjure
42
+ from edsl.language_models.ModelList import ModelList
edsl/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.29"
1
+ __version__ = "0.1.29.dev1"
edsl/agents/Agent.py CHANGED
@@ -5,14 +5,27 @@ import copy
5
5
  import inspect
6
6
  import types
7
7
  from typing import Any, Callable, Optional, Union, Dict, Sequence
8
- from edsl.Base import Base
9
8
 
9
+ from rich.table import Table
10
+
11
+ from edsl.Base import Base
12
+ from edsl.questions.QuestionBase import QuestionBase
13
+ from edsl.language_models import LanguageModel
14
+ from edsl.surveys.MemoryPlan import MemoryPlan
10
15
  from edsl.exceptions.agents import (
11
16
  AgentCombinationError,
12
17
  AgentDirectAnswerFunctionError,
13
18
  AgentDynamicTraitsFunctionError,
14
19
  )
15
-
20
+ from edsl.agents.Invigilator import (
21
+ InvigilatorDebug,
22
+ InvigilatorHuman,
23
+ InvigilatorFunctional,
24
+ InvigilatorAI,
25
+ InvigilatorBase,
26
+ )
27
+ from edsl.language_models.registry import Model
28
+ from edsl.scenarios import Scenario
16
29
  from edsl.agents.descriptors import (
17
30
  TraitsDescriptor,
18
31
  CodebookDescriptor,
@@ -25,6 +38,10 @@ from edsl.utilities.decorators import (
25
38
  remove_edsl_version,
26
39
  )
27
40
  from edsl.data_transfer_models import AgentResponseDict
41
+ from edsl.prompts.library.agent_persona import AgentPersona
42
+ from edsl.data.Cache import Cache
43
+
44
+
28
45
  from edsl.utilities.restricted_python import create_restricted_function
29
46
 
30
47
 
@@ -39,7 +56,6 @@ class Agent(Base):
39
56
  name = NameDescriptor()
40
57
  dynamic_traits_function_name = ""
41
58
  answer_question_directly_function_name = ""
42
- has_dynamic_traits_function = False
43
59
 
44
60
  def __init__(
45
61
  self,
@@ -113,16 +129,12 @@ class Agent(Base):
113
129
 
114
130
  if self.dynamic_traits_function:
115
131
  self.dynamic_traits_function_name = self.dynamic_traits_function.__name__
116
- self.has_dynamic_traits_function = True
117
- else:
118
- self.has_dynamic_traits_function = False
119
132
 
120
133
  if dynamic_traits_function_source_code:
121
134
  self.dynamic_traits_function_name = dynamic_traits_function_name
122
135
  self.dynamic_traits_function = create_restricted_function(
123
136
  dynamic_traits_function_name, dynamic_traits_function
124
137
  )
125
-
126
138
  if answer_question_directly_source_code:
127
139
  self.answer_question_directly_function_name = (
128
140
  answer_question_directly_function_name
@@ -139,8 +151,6 @@ class Agent(Base):
139
151
  self.current_question = None
140
152
 
141
153
  if traits_presentation_template is not None:
142
- from edsl.prompts.library.agent_persona import AgentPersona
143
-
144
154
  self.traits_presentation_template = traits_presentation_template
145
155
  self.agent_persona = AgentPersona(text=self.traits_presentation_template)
146
156
 
@@ -149,7 +159,7 @@ class Agent(Base):
149
159
 
150
160
  This checks whether the dynamic traits function is valid.
151
161
  """
152
- if self.has_dynamic_traits_function:
162
+ if self.dynamic_traits_function is not None:
153
163
  sig = inspect.signature(self.dynamic_traits_function)
154
164
  if "question" in sig.parameters:
155
165
  if len(sig.parameters) > 1:
@@ -179,7 +189,7 @@ class Agent(Base):
179
189
  {'age': 10, 'hair': 'brown', 'height': 5.5}
180
190
 
181
191
  """
182
- if self.has_dynamic_traits_function:
192
+ if self.dynamic_traits_function is not None:
183
193
  sig = inspect.signature(self.dynamic_traits_function)
184
194
  if "question" in sig.parameters:
185
195
  return self.dynamic_traits_function(question=self.current_question)
@@ -261,9 +271,8 @@ class Agent(Base):
261
271
  def create_invigilator(
262
272
  self,
263
273
  *,
264
- question: "QuestionBase",
265
- cache: "Cache",
266
- survey: Optional["Survey"] = None,
274
+ question: QuestionBase,
275
+ cache,
267
276
  scenario: Optional[Scenario] = None,
268
277
  model: Optional[LanguageModel] = None,
269
278
  debug: bool = False,
@@ -271,7 +280,7 @@ class Agent(Base):
271
280
  current_answers: Optional[dict] = None,
272
281
  iteration: int = 1,
273
282
  sidecar_model=None,
274
- ) -> "InvigilatorBase":
283
+ ) -> InvigilatorBase:
275
284
  """Create an Invigilator.
276
285
 
277
286
  An invigilator is an object that is responsible for administering a question to an agent.
@@ -285,8 +294,6 @@ class Agent(Base):
285
294
  An invigator is an object that is responsible for administering a question to an agent and
286
295
  recording the responses.
287
296
  """
288
- from edsl import Model, Scenario
289
-
290
297
  cache = cache
291
298
  self.current_question = question
292
299
  model = model or Model()
@@ -294,7 +301,6 @@ class Agent(Base):
294
301
  invigilator = self._create_invigilator(
295
302
  question=question,
296
303
  scenario=scenario,
297
- survey=survey,
298
304
  model=model,
299
305
  debug=debug,
300
306
  memory_plan=memory_plan,
@@ -308,13 +314,12 @@ class Agent(Base):
308
314
  async def async_answer_question(
309
315
  self,
310
316
  *,
311
- question: "QuestionBase",
312
- cache: "Cache",
313
- scenario: Optional["Scenario"] = None,
314
- survey: Optional["Survey"] = None,
315
- model: Optional["LanguageModel"] = None,
317
+ question: QuestionBase,
318
+ cache: Cache,
319
+ scenario: Optional[Scenario] = None,
320
+ model: Optional[LanguageModel] = None,
316
321
  debug: bool = False,
317
- memory_plan: Optional["MemoryPlan"] = None,
322
+ memory_plan: Optional[MemoryPlan] = None,
318
323
  current_answers: Optional[dict] = None,
319
324
  iteration: int = 0,
320
325
  ) -> AgentResponseDict:
@@ -344,7 +349,6 @@ class Agent(Base):
344
349
  question=question,
345
350
  cache=cache,
346
351
  scenario=scenario,
347
- survey=survey,
348
352
  model=model,
349
353
  debug=debug,
350
354
  memory_plan=memory_plan,
@@ -358,35 +362,21 @@ class Agent(Base):
358
362
 
359
363
  def _create_invigilator(
360
364
  self,
361
- question: "QuestionBase",
362
- cache: Optional["Cache"] = None,
363
- scenario: Optional["Scenario"] = None,
364
- model: Optional["LanguageModel"] = None,
365
- survey: Optional["Survey"] = None,
365
+ question: QuestionBase,
366
+ cache: Optional[Cache] = None,
367
+ scenario: Optional[Scenario] = None,
368
+ model: Optional[LanguageModel] = None,
366
369
  debug: bool = False,
367
- memory_plan: Optional["MemoryPlan"] = None,
370
+ memory_plan: Optional[MemoryPlan] = None,
368
371
  current_answers: Optional[dict] = None,
369
372
  iteration: int = 0,
370
373
  sidecar_model=None,
371
- ) -> "InvigilatorBase":
374
+ ) -> InvigilatorBase:
372
375
  """Create an Invigilator."""
373
- from edsl import Model
374
- from edsl import Scenario
375
-
376
376
  model = model or Model()
377
377
  scenario = scenario or Scenario()
378
378
 
379
- from edsl.agents.Invigilator import (
380
- InvigilatorDebug,
381
- InvigilatorHuman,
382
- InvigilatorFunctional,
383
- InvigilatorAI,
384
- InvigilatorBase,
385
- )
386
-
387
379
  if cache is None:
388
- from edsl.data.Cache import Cache
389
-
390
380
  cache = Cache()
391
381
 
392
382
  if debug:
@@ -414,7 +404,6 @@ class Agent(Base):
414
404
  self,
415
405
  question=question,
416
406
  scenario=scenario,
417
- survey=survey,
418
407
  model=model,
419
408
  memory_plan=memory_plan,
420
409
  current_answers=current_answers,
@@ -490,29 +479,6 @@ class Agent(Base):
490
479
  """
491
480
  return self.data == other.data
492
481
 
493
- def __getattr__(self, name):
494
- # This will be called only if 'name' is not found in the usual places
495
- # breakpoint()
496
- if name == "has_dynamic_traits_function":
497
- return self.has_dynamic_traits_function
498
-
499
- if name in self.traits:
500
- return self.traits[name]
501
- raise AttributeError(
502
- f"'{type(self).__name__}' object has no attribute '{name}'"
503
- )
504
-
505
- def __getstate__(self):
506
- state = self.__dict__.copy()
507
- # Include any additional state that needs to be serialized
508
- return state
509
-
510
- def __setstate__(self, state):
511
- self.__dict__.update(state)
512
- # Ensure _traits is initialized if it's missing
513
- if "_traits" not in self.__dict__:
514
- self._traits = {}
515
-
516
482
  def print(self) -> None:
517
483
  from rich import print_json
518
484
  import json
@@ -569,9 +535,9 @@ class Agent(Base):
569
535
  if dynamic_traits_func:
570
536
  func = inspect.getsource(dynamic_traits_func)
571
537
  raw_data["dynamic_traits_function_source_code"] = func
572
- raw_data["dynamic_traits_function_name"] = (
573
- self.dynamic_traits_function_name
574
- )
538
+ raw_data[
539
+ "dynamic_traits_function_name"
540
+ ] = self.dynamic_traits_function_name
575
541
  if hasattr(self, "answer_question_directly"):
576
542
  raw_data.pop(
577
543
  "answer_question_directly", None
@@ -587,9 +553,9 @@ class Agent(Base):
587
553
  raw_data["answer_question_directly_source_code"] = inspect.getsource(
588
554
  answer_question_directly_func
589
555
  )
590
- raw_data["answer_question_directly_function_name"] = (
591
- self.answer_question_directly_function_name
592
- )
556
+ raw_data[
557
+ "answer_question_directly_function_name"
558
+ ] = self.answer_question_directly_function_name
593
559
 
594
560
  return raw_data
595
561
 
@@ -674,8 +640,6 @@ class Agent(Base):
674
640
  >>> a.rich_print()
675
641
  <rich.table.Table object at ...>
676
642
  """
677
- from rich.table import Table
678
-
679
643
  table_data, column_names = self._table()
680
644
  table = Table(title=f"{self.__class__.__name__} Attributes")
681
645
  for column in column_names:
edsl/agents/AgentList.py CHANGED
@@ -12,7 +12,7 @@ Example usage:
12
12
 
13
13
  from __future__ import annotations
14
14
  from collections import UserList
15
- from typing import Optional, Union, Sequence, List, Any
15
+ from typing import Optional, Union, Sequence
16
16
  from rich import print_json
17
17
  from rich.table import Table
18
18
  import json
@@ -22,8 +22,7 @@ import csv
22
22
  from simpleeval import EvalWithCompoundTypes
23
23
 
24
24
  from edsl.Base import Base
25
-
26
- # from edsl.agents import Agent
25
+ from edsl.agents import Agent
27
26
  from edsl.utilities.decorators import (
28
27
  add_edsl_version,
29
28
  remove_edsl_version,
@@ -33,7 +32,7 @@ from edsl.utilities.decorators import (
33
32
  class AgentList(UserList, Base):
34
33
  """A list of Agents."""
35
34
 
36
- def __init__(self, data: Optional[list["Agent"]] = None):
35
+ def __init__(self, data: Optional[list[Agent]] = None):
37
36
  """Initialize a new AgentList.
38
37
 
39
38
  :param data: A list of Agents.
@@ -78,7 +77,6 @@ class AgentList(UserList, Base):
78
77
  def select(self, *traits) -> AgentList:
79
78
  """Selects agents with only the references traits.
80
79
 
81
- >>> from edsl.agents.Agent import Agent
82
80
  >>> al = AgentList([Agent(traits = {'a': 1, 'b': 1}), Agent(traits = {'a': 1, 'b': 2})])
83
81
  >>> al.select('a')
84
82
  AgentList([Agent(traits = {'a': 1}), Agent(traits = {'a': 1})])
@@ -96,13 +94,12 @@ class AgentList(UserList, Base):
96
94
  """
97
95
  Filter a list of agents based on an expression.
98
96
 
99
- >>> from edsl.agents.Agent import Agent
100
97
  >>> al = AgentList([Agent(traits = {'a': 1, 'b': 1}), Agent(traits = {'a': 1, 'b': 2})])
101
98
  >>> al.filter("b == 2")
102
99
  AgentList([Agent(traits = {'a': 1, 'b': 2})])
103
100
  """
104
101
 
105
- def create_evaluator(agent: "Agent"):
102
+ def create_evaluator(agent: Agent):
106
103
  """Create an evaluator for the given result.
107
104
  The 'combined_dict' is a mapping of all values for that Result object.
108
105
  """
@@ -136,8 +133,6 @@ class AgentList(UserList, Base):
136
133
 
137
134
  :param file_path: The path to the CSV file.
138
135
  """
139
- from edsl.agents.Agent import Agent
140
-
141
136
  agent_list = []
142
137
  with open(file_path, "r") as f:
143
138
  reader = csv.DictReader(f)
@@ -158,7 +153,7 @@ class AgentList(UserList, Base):
158
153
  """Remove traits from the AgentList.
159
154
 
160
155
  :param traits: The traits to remove.
161
- >>> from edsl.agents.Agent import Agent
156
+
162
157
  >>> al = AgentList([Agent({'age': 22, 'hair': 'brown', 'height': 5.5}), Agent({'age': 22, 'hair': 'brown', 'height': 5.5})])
163
158
  >>> al.remove_trait('age')
164
159
  AgentList([Agent(traits = {'hair': 'brown', 'height': 5.5}), Agent(traits = {'hair': 'brown', 'height': 5.5})])
@@ -227,14 +222,12 @@ class AgentList(UserList, Base):
227
222
  """Deserialize the dictionary back to an AgentList object.
228
223
 
229
224
  :param: data: A dictionary representing an AgentList.
230
- >>> from edsl.agents.Agent import Agent
225
+
231
226
  >>> al = AgentList([Agent.example(), Agent.example()])
232
227
  >>> al2 = AgentList.from_dict(al.to_dict())
233
228
  >>> al2 == al
234
229
  True
235
230
  """
236
- from edsl.agents.Agent import Agent
237
-
238
231
  agents = [Agent.from_dict(agent_dict) for agent_dict in data["agent_list"]]
239
232
  return cls(agents)
240
233
 
@@ -247,30 +240,8 @@ class AgentList(UserList, Base):
247
240
  2
248
241
 
249
242
  """
250
- from edsl.agents.Agent import Agent
251
-
252
243
  return cls([Agent.example(), Agent.example()])
253
244
 
254
- @classmethod
255
- def from_list(self, trait_name: str, values: List[Any]):
256
- """Create an AgentList from a list of values.
257
-
258
- :param trait_name: The name of the trait.
259
- :param values: A list of values.
260
- """
261
- from edsl.agents.Agent import Agent
262
-
263
- return AgentList([Agent({trait_name: value}) for value in values])
264
-
265
- def __mul__(self, other: AgentList) -> AgentList:
266
- """Takes the cross product of two AgentLists."""
267
- from itertools import product
268
-
269
- new_sl = []
270
- for s1, s2 in list(product(self, other)):
271
- new_sl.append(s1 + s2)
272
- return AgentList(new_sl)
273
-
274
245
  def code(self, string=True) -> Union[str, list[str]]:
275
246
  """Return code to construct an AgentList.
276
247
 
@@ -82,25 +82,7 @@ class InvigilatorAI(PromptConstructorMixin, InvigilatorBase):
82
82
  self._remove_from_cache(raw_response)
83
83
  raise e
84
84
 
85
- # breakpoint()
86
- question_dict = self.survey.question_names_to_questions()
87
- for other_question, answer in self.current_answers.items():
88
- if other_question in question_dict:
89
- question_dict[other_question].answer = answer
90
- else:
91
- # adds a comment to the question
92
- if (
93
- new_question := other_question.split("_comment")[0]
94
- ) in question_dict:
95
- question_dict[new_question].comment = answer
96
-
97
- combined_dict = {**question_dict, **scenario}
98
- # print("combined_dict: ", combined_dict)
99
- # print("response: ", response)
100
- # breakpoint()
101
- answer = question._translate_answer_code_to_answer(
102
- response["answer"], combined_dict
103
- )
85
+ answer = question._translate_answer_code_to_answer(response["answer"], scenario)
104
86
  data = {
105
87
  "answer": answer,
106
88
  "comment": response.get(
@@ -46,7 +46,6 @@ class InvigilatorBase(ABC):
46
46
  model: LanguageModel,
47
47
  memory_plan: MemoryPlan,
48
48
  current_answers: dict,
49
- survey: Optional["Survey"],
50
49
  cache: Optional[Cache] = None,
51
50
  iteration: Optional[int] = 1,
52
51
  additional_prompt_data: Optional[dict] = None,
@@ -58,12 +57,11 @@ class InvigilatorBase(ABC):
58
57
  self.scenario = scenario
59
58
  self.model = model
60
59
  self.memory_plan = memory_plan
61
- self.current_answers = current_answers or {}
60
+ self.current_answers = current_answers
62
61
  self.iteration = iteration
63
62
  self.additional_prompt_data = additional_prompt_data
64
63
  self.cache = cache
65
64
  self.sidecar_model = sidecar_model
66
- self.survey = survey
67
65
 
68
66
  def __repr__(self) -> str:
69
67
  """Return a string representation of the Invigilator.
@@ -78,7 +76,7 @@ class InvigilatorBase(ABC):
78
76
  """Return an AgentResponseDict used in case the question-asking fails.
79
77
 
80
78
  >>> InvigilatorBase.example().get_failed_task_result()
81
- {'answer': None, 'comment': 'Failed to get response', ...}
79
+ {'answer': None, 'comment': 'Failed to get response', 'question_name': 'how_feeling', ...}
82
80
  """
83
81
  return AgentResponseDict(
84
82
  answer=None,
@@ -88,8 +86,11 @@ class InvigilatorBase(ABC):
88
86
  )
89
87
 
90
88
  def get_prompts(self) -> Dict[str, Prompt]:
91
- """Return the prompt used."""
89
+ """Return the prompt used.
92
90
 
91
+ >>> InvigilatorBase.example().get_prompts()
92
+ {'user_prompt': Prompt(text=\"""NA\"""), 'system_prompt': Prompt(text=\"""NA\""")}
93
+ """
93
94
  return {
94
95
  "user_prompt": Prompt("NA"),
95
96
  "system_prompt": Prompt("NA"),
@@ -128,7 +129,7 @@ class InvigilatorBase(ABC):
128
129
  )
129
130
 
130
131
  @classmethod
131
- def example(cls, throw_an_exception=False, question=None, scenario=None):
132
+ def example(cls, throw_an_exception=False):
132
133
  """Return an example invigilator.
133
134
 
134
135
  >>> InvigilatorBase.example()
@@ -166,20 +167,15 @@ class InvigilatorBase(ABC):
166
167
  if throw_an_exception:
167
168
  model.throw_an_exception = True
168
169
  agent = Agent.example()
169
- # question = QuestionMultipleChoice.example()
170
- from edsl.surveys import Survey
171
-
172
- survey = Survey.example()
173
- question = question or survey.questions[0]
174
- scenario = scenario or Scenario.example()
170
+ question = QuestionMultipleChoice.example()
171
+ scenario = Scenario.example()
175
172
  # memory_plan = None #memory_plan = MemoryPlan()
176
173
  from edsl import Survey
177
174
 
178
175
  memory_plan = MemoryPlan(survey=Survey.example())
179
176
  current_answers = None
180
- from edsl.agents.PromptConstructionMixin import PromptConstructorMixin
181
177
 
182
- class InvigilatorExample(PromptConstructorMixin, InvigilatorBase):
178
+ class InvigilatorExample(InvigilatorBase):
183
179
  """An example invigilator."""
184
180
 
185
181
  async def async_answer_question(self):
@@ -192,7 +188,6 @@ class InvigilatorBase(ABC):
192
188
  agent=agent,
193
189
  question=question,
194
190
  scenario=scenario,
195
- survey=survey,
196
191
  model=model,
197
192
  memory_plan=memory_plan,
198
193
  current_answers=current_answers,