edsl 0.1.29.dev2__py3-none-any.whl → 0.1.29.dev6__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 CHANGED
@@ -52,31 +52,28 @@ class PersistenceMixin:
52
52
  return c.create(self, description, visibility)
53
53
 
54
54
  @classmethod
55
- def pull(cls, id_or_url: Union[str, UUID], exec_profile=None):
55
+ def pull(cls, uuid: Optional[Union[str, UUID]] = None, url: Optional[str] = None):
56
56
  """Pull the object from coop."""
57
57
  from edsl.coop import Coop
58
+ from edsl.coop.utils import ObjectRegistry
58
59
 
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)
60
+ object_type = ObjectRegistry.get_object_type_by_edsl_class(cls)
61
+ coop = Coop()
62
+ return coop.get(uuid, url, object_type)
67
63
 
68
64
  @classmethod
69
- def delete(cls, id_or_url: Union[str, UUID]):
65
+ def delete(cls, uuid: Optional[Union[str, UUID]] = None, url: Optional[str] = None):
70
66
  """Delete the object from coop."""
71
67
  from edsl.coop import Coop
72
68
 
73
- c = Coop()
74
- return c._delete_base(cls, id_or_url)
69
+ coop = Coop()
70
+ return coop.delete(uuid, url)
75
71
 
76
72
  @classmethod
77
73
  def patch(
78
74
  cls,
79
- id_or_url: Union[str, UUID],
75
+ uuid: Optional[Union[str, UUID]] = None,
76
+ url: Optional[str] = None,
80
77
  description: Optional[str] = None,
81
78
  value: Optional[Any] = None,
82
79
  visibility: Optional[str] = None,
@@ -89,8 +86,8 @@ class PersistenceMixin:
89
86
  """
90
87
  from edsl.coop import Coop
91
88
 
92
- c = Coop()
93
- return c._patch_base(cls, id_or_url, description, value, visibility)
89
+ coop = Coop()
90
+ return coop.patch(uuid, url, description, value, visibility)
94
91
 
95
92
  @classmethod
96
93
  def search(cls, query):
edsl/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.1.29.dev2"
1
+ __version__ = "0.1.29.dev6"
edsl/agents/Agent.py CHANGED
@@ -56,6 +56,7 @@ class Agent(Base):
56
56
  name = NameDescriptor()
57
57
  dynamic_traits_function_name = ""
58
58
  answer_question_directly_function_name = ""
59
+ has_dynamic_traits_function = False
59
60
 
60
61
  def __init__(
61
62
  self,
@@ -129,12 +130,16 @@ class Agent(Base):
129
130
 
130
131
  if self.dynamic_traits_function:
131
132
  self.dynamic_traits_function_name = self.dynamic_traits_function.__name__
133
+ self.has_dynamic_traits_function = True
134
+ else:
135
+ self.has_dynamic_traits_function = False
132
136
 
133
137
  if dynamic_traits_function_source_code:
134
138
  self.dynamic_traits_function_name = dynamic_traits_function_name
135
139
  self.dynamic_traits_function = create_restricted_function(
136
140
  dynamic_traits_function_name, dynamic_traits_function
137
141
  )
142
+
138
143
  if answer_question_directly_source_code:
139
144
  self.answer_question_directly_function_name = (
140
145
  answer_question_directly_function_name
@@ -159,7 +164,7 @@ class Agent(Base):
159
164
 
160
165
  This checks whether the dynamic traits function is valid.
161
166
  """
162
- if self.dynamic_traits_function is not None:
167
+ if self.has_dynamic_traits_function:
163
168
  sig = inspect.signature(self.dynamic_traits_function)
164
169
  if "question" in sig.parameters:
165
170
  if len(sig.parameters) > 1:
@@ -189,7 +194,7 @@ class Agent(Base):
189
194
  {'age': 10, 'hair': 'brown', 'height': 5.5}
190
195
 
191
196
  """
192
- if self.dynamic_traits_function is not None:
197
+ if self.has_dynamic_traits_function:
193
198
  sig = inspect.signature(self.dynamic_traits_function)
194
199
  if "question" in sig.parameters:
195
200
  return self.dynamic_traits_function(question=self.current_question)
@@ -273,6 +278,7 @@ class Agent(Base):
273
278
  *,
274
279
  question: QuestionBase,
275
280
  cache,
281
+ survey: Optional["Survey"] = None,
276
282
  scenario: Optional[Scenario] = None,
277
283
  model: Optional[LanguageModel] = None,
278
284
  debug: bool = False,
@@ -301,6 +307,7 @@ class Agent(Base):
301
307
  invigilator = self._create_invigilator(
302
308
  question=question,
303
309
  scenario=scenario,
310
+ survey=survey,
304
311
  model=model,
305
312
  debug=debug,
306
313
  memory_plan=memory_plan,
@@ -317,6 +324,7 @@ class Agent(Base):
317
324
  question: QuestionBase,
318
325
  cache: Cache,
319
326
  scenario: Optional[Scenario] = None,
327
+ survey: Optional["Survey"] = None,
320
328
  model: Optional[LanguageModel] = None,
321
329
  debug: bool = False,
322
330
  memory_plan: Optional[MemoryPlan] = None,
@@ -349,6 +357,7 @@ class Agent(Base):
349
357
  question=question,
350
358
  cache=cache,
351
359
  scenario=scenario,
360
+ survey=survey,
352
361
  model=model,
353
362
  debug=debug,
354
363
  memory_plan=memory_plan,
@@ -366,6 +375,7 @@ class Agent(Base):
366
375
  cache: Optional[Cache] = None,
367
376
  scenario: Optional[Scenario] = None,
368
377
  model: Optional[LanguageModel] = None,
378
+ survey: Optional["Survey"] = None,
369
379
  debug: bool = False,
370
380
  memory_plan: Optional[MemoryPlan] = None,
371
381
  current_answers: Optional[dict] = None,
@@ -404,6 +414,7 @@ class Agent(Base):
404
414
  self,
405
415
  question=question,
406
416
  scenario=scenario,
417
+ survey=survey,
407
418
  model=model,
408
419
  memory_plan=memory_plan,
409
420
  current_answers=current_answers,
@@ -479,6 +490,30 @@ class Agent(Base):
479
490
  """
480
491
  return self.data == other.data
481
492
 
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
+
506
+ def __getstate__(self):
507
+ state = self.__dict__.copy()
508
+ # Include any additional state that needs to be serialized
509
+ return state
510
+
511
+ def __setstate__(self, state):
512
+ self.__dict__.update(state)
513
+ # Ensure _traits is initialized if it's missing
514
+ if "_traits" not in self.__dict__:
515
+ self._traits = {}
516
+
482
517
  def print(self) -> None:
483
518
  from rich import print_json
484
519
  import json
edsl/agents/AgentList.py CHANGED
@@ -241,16 +241,16 @@ class AgentList(UserList, Base):
241
241
 
242
242
  """
243
243
  return cls([Agent.example(), Agent.example()])
244
-
244
+
245
245
  @classmethod
246
- def from_list(self, trait_name:str, values: List[Any]):
246
+ def from_list(self, trait_name: str, values: List[Any]):
247
247
  """Create an AgentList from a list of values.
248
248
 
249
249
  :param trait_name: The name of the trait.
250
250
  :param values: A list of values.
251
251
  """
252
252
  return AgentList([Agent({trait_name: value}) for value in values])
253
-
253
+
254
254
  def __mul__(self, other: AgentList) -> AgentList:
255
255
  """Takes the cross product of two AgentLists."""
256
256
  from itertools import product
@@ -260,7 +260,6 @@ class AgentList(UserList, Base):
260
260
  new_sl.append(s1 + s2)
261
261
  return AgentList(new_sl)
262
262
 
263
-
264
263
  def code(self, string=True) -> Union[str, list[str]]:
265
264
  """Return code to construct an AgentList.
266
265
 
@@ -46,6 +46,7 @@ class InvigilatorBase(ABC):
46
46
  model: LanguageModel,
47
47
  memory_plan: MemoryPlan,
48
48
  current_answers: dict,
49
+ survey: Optional["Survey"],
49
50
  cache: Optional[Cache] = None,
50
51
  iteration: Optional[int] = 1,
51
52
  additional_prompt_data: Optional[dict] = None,
@@ -57,11 +58,12 @@ class InvigilatorBase(ABC):
57
58
  self.scenario = scenario
58
59
  self.model = model
59
60
  self.memory_plan = memory_plan
60
- self.current_answers = current_answers
61
+ self.current_answers = current_answers or {}
61
62
  self.iteration = iteration
62
63
  self.additional_prompt_data = additional_prompt_data
63
64
  self.cache = cache
64
65
  self.sidecar_model = sidecar_model
66
+ self.survey = survey
65
67
 
66
68
  def __repr__(self) -> str:
67
69
  """Return a string representation of the Invigilator.
@@ -76,7 +78,7 @@ class InvigilatorBase(ABC):
76
78
  """Return an AgentResponseDict used in case the question-asking fails.
77
79
 
78
80
  >>> InvigilatorBase.example().get_failed_task_result()
79
- {'answer': None, 'comment': 'Failed to get response', 'question_name': 'how_feeling', ...}
81
+ {'answer': None, 'comment': 'Failed to get response', ...}
80
82
  """
81
83
  return AgentResponseDict(
82
84
  answer=None,
@@ -86,11 +88,8 @@ class InvigilatorBase(ABC):
86
88
  )
87
89
 
88
90
  def get_prompts(self) -> Dict[str, Prompt]:
89
- """Return the prompt used.
91
+ """Return the prompt used."""
90
92
 
91
- >>> InvigilatorBase.example().get_prompts()
92
- {'user_prompt': Prompt(text=\"""NA\"""), 'system_prompt': Prompt(text=\"""NA\""")}
93
- """
94
93
  return {
95
94
  "user_prompt": Prompt("NA"),
96
95
  "system_prompt": Prompt("NA"),
@@ -129,7 +128,7 @@ class InvigilatorBase(ABC):
129
128
  )
130
129
 
131
130
  @classmethod
132
- def example(cls, throw_an_exception=False):
131
+ def example(cls, throw_an_exception=False, question=None, scenario=None):
133
132
  """Return an example invigilator.
134
133
 
135
134
  >>> InvigilatorBase.example()
@@ -167,15 +166,20 @@ class InvigilatorBase(ABC):
167
166
  if throw_an_exception:
168
167
  model.throw_an_exception = True
169
168
  agent = Agent.example()
170
- question = QuestionMultipleChoice.example()
171
- scenario = Scenario.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()
172
175
  # memory_plan = None #memory_plan = MemoryPlan()
173
176
  from edsl import Survey
174
177
 
175
178
  memory_plan = MemoryPlan(survey=Survey.example())
176
179
  current_answers = None
180
+ from edsl.agents.PromptConstructionMixin import PromptConstructorMixin
177
181
 
178
- class InvigilatorExample(InvigilatorBase):
182
+ class InvigilatorExample(PromptConstructorMixin, InvigilatorBase):
179
183
  """An example invigilator."""
180
184
 
181
185
  async def async_answer_question(self):
@@ -188,6 +192,7 @@ class InvigilatorBase(ABC):
188
192
  agent=agent,
189
193
  question=question,
190
194
  scenario=scenario,
195
+ survey=survey,
191
196
  model=model,
192
197
  memory_plan=memory_plan,
193
198
  current_answers=current_answers,