pycityagent 2.0.0a59__cp310-cp310-macosx_11_0_arm64.whl → 2.0.0a61__cp310-cp310-macosx_11_0_arm64.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.
@@ -94,24 +94,19 @@ class CitizenAgent(Agent):
94
94
  logger.warning("Economy client is not set")
95
95
  return
96
96
  if not self._has_bound_to_economy:
97
- if self._has_bound_to_simulator:
98
- try:
99
- await self._economy_client.remove_agents([self._agent_id])
100
- except:
101
- pass
102
- person_id = await self.status.get("id")
103
- currency = await self.status.get("currency")
104
- await self._economy_client.add_agents(
105
- {
106
- "id": person_id,
107
- "currency": currency,
108
- }
109
- )
110
- self._has_bound_to_economy = True
111
- else:
112
- logger.debug(
113
- f"Binding to Economy before binding to Simulator, skip binding to Economy Simulator"
114
- )
97
+ try:
98
+ await self._economy_client.remove_agents([self._agent_id])
99
+ except:
100
+ pass
101
+ person_id = await self.status.get("id")
102
+ currency = await self.status.get("currency")
103
+ await self._economy_client.add_agents(
104
+ {
105
+ "id": person_id,
106
+ "currency": currency,
107
+ }
108
+ )
109
+ self._has_bound_to_economy = True
115
110
 
116
111
  async def handle_gather_message(self, payload: dict):
117
112
  """处理收到的消息,识别发送者"""
@@ -176,7 +171,6 @@ class InstitutionAgent(Agent):
176
171
  await self._bind_to_economy()
177
172
 
178
173
  async def _bind_to_economy(self):
179
- print("Debug:", self._economy_client, self._has_bound_to_economy)
180
174
  if self._economy_client is None:
181
175
  logger.debug("Economy client is not set")
182
176
  return
@@ -55,6 +55,10 @@ class EdgeMessageBlock(MessageBlockBase):
55
55
 
56
56
 
57
57
  class PointMessageBlock(MessageBlockBase):
58
+ def __init__(self, name: str = "", max_violation_time: int = 3) -> None:
59
+ super().__init__(name)
60
+ self.max_violation_time = max_violation_time
61
+
58
62
  async def forward( # type:ignore
59
63
  self,
60
64
  from_uuid: str,
@@ -74,7 +78,10 @@ class PointMessageBlock(MessageBlockBase):
74
78
  llm_client=self.llm,
75
79
  content=msg,
76
80
  )
77
- if not is_valid and violation_counts[from_uuid] >= 3 - 1:
81
+ if (
82
+ not is_valid
83
+ and violation_counts[from_uuid] >= self.max_violation_time - 1
84
+ ):
78
85
  # 直接添加即可 在框架内部的异步锁保证不会冲突
79
86
  black_list.append((from_uuid, to_uuid))
80
87
  return is_valid
Binary file
@@ -13,13 +13,16 @@ import yaml
13
13
  from langchain_core.embeddings import Embeddings
14
14
 
15
15
  from ..agent import Agent, InstitutionAgent
16
- from ..cityagent import (BankAgent, FirmAgent, GovernmentAgent, NBSAgent,SocietyAgent,
17
- memory_config_bank, memory_config_firm,
16
+ from ..cityagent import (BankAgent, FirmAgent, GovernmentAgent, NBSAgent,
17
+ SocietyAgent, memory_config_bank, memory_config_firm,
18
18
  memory_config_government, memory_config_nbs,
19
19
  memory_config_societyagent)
20
20
  from ..cityagent.initial import bind_agent_info, initialize_social_network
21
- from ..environment import Simulator
21
+ from ..cityagent.message_intercept import (EdgeMessageBlock,
22
+ MessageBlockListener,
23
+ PointMessageBlock)
22
24
  from ..economy.econ_client import EconomyClient
25
+ from ..environment import Simulator
23
26
  from ..llm import SimpleEmbedding
24
27
  from ..message import (MessageBlockBase, MessageBlockListenerBase,
25
28
  MessageInterceptor, Messager)
@@ -75,7 +78,9 @@ class AgentSimulation:
75
78
  }
76
79
  else:
77
80
  self.agent_class = [SocietyAgent]
78
- self.default_memory_config_func = {SocietyAgent: memory_config_societyagent}
81
+ self.default_memory_config_func = {
82
+ SocietyAgent: memory_config_societyagent
83
+ }
79
84
  else:
80
85
  self.agent_class = [agent_class]
81
86
  self.agent_config_file = agent_config_file
@@ -229,6 +234,9 @@ class AgentSimulation:
229
234
  - times: int if type is "step", else None
230
235
  - description: Optional[str], description of the step
231
236
  - func: Optional[Callable[AgentSimulation, None]], only used when type is "interview", "survey" and "intervene"
237
+ - message_intercept
238
+ - mode: "point"|"edge"
239
+ - max_violation_time: Optional[int], default to 3. The maximum time for someone to send bad message before banned. Used only in `point` mode.
232
240
  - logging_level: Optional[int]
233
241
  - exp_name: Optional[str]
234
242
  """
@@ -260,7 +268,31 @@ class AgentSimulation:
260
268
  agent_count.append(config["agent_config"]["number_of_government"])
261
269
  agent_count.append(config["agent_config"]["number_of_bank"])
262
270
  agent_count.append(config["agent_config"]["number_of_nbs"])
263
- # TODO(yanjunbo): support MessageInterceptor
271
+ # support MessageInterceptor
272
+ if "message_intercept" in config:
273
+ _intercept_config = config["message_intercept"]
274
+ _mode = _intercept_config.get("mode", "point")
275
+ if _mode == "point":
276
+ _kwargs = {
277
+ k: v
278
+ for k, v in _intercept_config.items()
279
+ if k
280
+ in {
281
+ "max_violation_time",
282
+ }
283
+ }
284
+ _interceptor_blocks = [PointMessageBlock(**_kwargs)]
285
+ elif _mode == "edge":
286
+ _kwargs = {}
287
+ _interceptor_blocks = [EdgeMessageBlock(**_kwargs)]
288
+ else:
289
+ raise ValueError(f"Unsupported interception mode `{_mode}!`")
290
+ _message_intercept_kwargs = {
291
+ "message_interceptor_blocks": _interceptor_blocks,
292
+ "message_listener": MessageBlockListener(),
293
+ }
294
+ else:
295
+ _message_intercept_kwargs = {}
264
296
  await simulation.init_agents(
265
297
  agent_count=agent_count,
266
298
  group_size=config["agent_config"].get("group_size", 10000),
@@ -268,6 +300,7 @@ class AgentSimulation:
268
300
  "embedding_model", SimpleEmbedding()
269
301
  ),
270
302
  memory_config_func=config["agent_config"].get("memory_config_func", None),
303
+ **_message_intercept_kwargs,
271
304
  )
272
305
  logger.info("Running Init Functions...")
273
306
  for init_func in config["agent_config"].get(
@@ -312,7 +345,7 @@ class AgentSimulation:
312
345
  self,
313
346
  ) -> Path:
314
347
  return self._avro_path # type:ignore
315
-
348
+
316
349
  @property
317
350
  def economy_client(self):
318
351
  return self._economy_client
@@ -438,7 +471,7 @@ class AgentSimulation:
438
471
  raise ValueError("agent_class和agent_count的长度不一致")
439
472
 
440
473
  if memory_config_func is None:
441
- memory_config_func = self.default_memory_config_func
474
+ memory_config_func = self.default_memory_config_func # type:ignore
442
475
 
443
476
  # 使用线程池并行创建 AgentGroup
444
477
  group_creation_params = []
@@ -451,7 +484,10 @@ class AgentSimulation:
451
484
  for i in range(len(self.agent_class)):
452
485
  agent_class = self.agent_class[i]
453
486
  agent_count_i = agent_count[i]
454
- memory_config_func_i = memory_config_func.get(agent_class, self.default_memory_config_func[agent_class])
487
+ assert memory_config_func is not None
488
+ memory_config_func_i = memory_config_func.get(
489
+ agent_class, self.default_memory_config_func[agent_class] # type:ignore
490
+ )
455
491
 
456
492
  if self.agent_config_file is not None:
457
493
  config_file = self.agent_config_file.get(agent_class, None)
@@ -564,6 +600,7 @@ class AgentSimulation:
564
600
  _num_workers = 1
565
601
  self._pgsql_writers = _workers = [None for _ in range(_num_workers)]
566
602
  # message interceptor
603
+ self.message_listener = message_listener
567
604
  if message_listener is not None:
568
605
  self._message_abort_listening_queue = _queue = ray.util.queue.Queue() # type: ignore
569
606
  await message_listener.set_queue(_queue)
@@ -688,18 +725,19 @@ class AgentSimulation:
688
725
  group = self._agent_uuid2group[target_agent_uuid]
689
726
  await group.update.remote(target_agent_uuid, target_key, content)
690
727
 
691
- async def economy_update(self, target_agent_id: int, target_key: str, content: Any, mode: Literal["replace", "merge"] = "replace"):
728
+ async def economy_update(
729
+ self,
730
+ target_agent_id: int,
731
+ target_key: str,
732
+ content: Any,
733
+ mode: Literal["replace", "merge"] = "replace",
734
+ ):
692
735
  """更新指定智能体的经济数据"""
693
- self.economy_client.update(
694
- id = target_agent_id,
695
- key = target_key,
696
- value=content,
697
- mode=mode
736
+ await self.economy_client.update(
737
+ id=target_agent_id, key=target_key, value=content, mode=mode
698
738
  )
699
739
 
700
- async def send_survey(
701
- self, survey: Survey, agent_uuids: list[str] = None
702
- ):
740
+ async def send_survey(self, survey: Survey, agent_uuids: list[str] = []):
703
741
  """发送问卷"""
704
742
  survey_dict = survey.to_dict()
705
743
  _date_time = datetime.now(timezone.utc)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pycityagent
3
- Version: 2.0.0a59
3
+ Version: 2.0.0a61
4
4
  Summary: LLM-based city environment agent building library
5
5
  Author-email: Yuwei Yan <pinkgranite86@gmail.com>, Junbo Yan <yanjb20thu@gmali.com>, Jun Zhang <zhangjun990222@gmali.com>
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- pycityagent/pycityagent-sim,sha256=1Nu-QYC0AuZyVWciGNa2XkYsUntbwAS15Bo7l-y6eok,35449490
1
+ pycityagent/pycityagent-sim,sha256=vskCJGHJEh0B2dUfmYlVyrcy3sDZ3kBNwjqcYUZpmO8,35449490
2
2
  pycityagent/__init__.py,sha256=PUKWTXc-xdMG7px8oTNclodsILUgypANj2Z647sY63k,808
3
3
  pycityagent/pycityagent-ui,sha256=cHZjqtrQ4Fh4qtRahFNCNbT2DNHLmUexiDAa-72Z3RQ,40333378
4
4
  pycityagent/metrics/mlflow_client.py,sha256=bTrqYsRfNfjJd6l91hU8vN7JXzJC7DHiM2XbkhMuXIU,4613
@@ -22,7 +22,7 @@ pycityagent/memory/utils.py,sha256=oJWLdPeJy_jcdKcDTo9JAH9kDZhqjoQhhv_zT9qWC0w,8
22
22
  pycityagent/memory/const.py,sha256=6zpJPJXWoH9-yf4RARYYff586agCoud9BRn7sPERB1g,932
23
23
  pycityagent/memory/faiss_query.py,sha256=V3rIw6d1_xcpNqZBbAYz3qfjVNE7NfJ7xOS5SibPtVU,13180
24
24
  pycityagent/memory/state.py,sha256=TYItiyDtehMEQaSBN7PpNrnNxdDM5jGppr9R9Ufv3kA,5134
25
- pycityagent/simulation/simulation.py,sha256=sbrX-e8gV2Wwi8k6ir7TVgQhzejpUZ85SfuiXO4E39I,33983
25
+ pycityagent/simulation/simulation.py,sha256=yDQBzIpxAEvr3oEt2PChgAhTnPgy2t4n-nbgCiqiE6s,35578
26
26
  pycityagent/simulation/__init__.py,sha256=P5czbcg2d8S0nbbnsQXFIhwzO4CennAhZM8OmKvAeYw,194
27
27
  pycityagent/simulation/agentgroup.py,sha256=V-ChLJtJUWJZnmTGllXqGk4XW4iDz9h3V89RgW0e4gg,31376
28
28
  pycityagent/simulation/storage/pg.py,sha256=xRshSOGttW-p0re0fNBOjOpb-nQ5msIE2LsdT79_E_Y,8425
@@ -40,7 +40,7 @@ pycityagent/utils/parsers/parser_base.py,sha256=KBKO4zLZPNdGjPAGqIus8LseZ8W3Tlt2
40
40
  pycityagent/utils/parsers/json_parser.py,sha256=tjwyPluYfkWgsvLi0hzfJwFhO3L6yQfZMKza20HaGrY,2911
41
41
  pycityagent/agent/agent_base.py,sha256=vC1nMWahwi_nVBUXVdC1CnZpqimKZApixD2m2Iqu_bg,24196
42
42
  pycityagent/agent/__init__.py,sha256=U20yKu9QwSqAx_PHk5JwipfODkDfxONtumVfnsKjWFg,180
43
- pycityagent/agent/agent.py,sha256=FNon_OPvGrh976AEHpaAQyLQN7erbGOX-BxGnCVZza8,12038
43
+ pycityagent/agent/agent.py,sha256=H5AXh92LZZzrGHH8dkwAVTKQIfI8a7xH-83iv50Qejs,11696
44
44
  pycityagent/cli/wrapper.py,sha256=9aG6D2cnmh6aIhiVXKPGKuMjVcdAa-TwzANudb2q_FU,1147
45
45
  pycityagent/workflow/__init__.py,sha256=H08Ko3eliZvuuCMajbEri-IP4-SeswYU6UjHBNA4Ze0,490
46
46
  pycityagent/workflow/prompt.py,sha256=6jI0Rq54JLv3-IXqZLYug62vse10wTI83xvf4ZX42nk,2929
@@ -82,7 +82,7 @@ pycityagent/cityagent/firmagent.py,sha256=UVlNN0lpa4cC4PZVqYzQhbc5VJ2oGsA1731mhb
82
82
  pycityagent/cityagent/nbsagent.py,sha256=WIXW__6dZ5IrqBqDCjvGbrCshpXzuFRV3Ww6gkYw7p4,4387
83
83
  pycityagent/cityagent/initial.py,sha256=7hgCt_tGdnVTXGfEQOn1GTW5dAs1b-ru_FwXxRLI6tM,4549
84
84
  pycityagent/cityagent/societyagent.py,sha256=DKkPtCPXTpHs83hi3bvXxkQYxKqZI0YldYCyFu4yjsk,24811
85
- pycityagent/cityagent/message_intercept.py,sha256=HiNOtBXKq40LCmvsw2KMLxMsbmXSVcbRytAO-eI-1sU,3279
85
+ pycityagent/cityagent/message_intercept.py,sha256=2RI4--5SVQy9aLXulxxldzmwOynwAKFqtmBaFUnEtsk,3511
86
86
  pycityagent/cityagent/governmentagent.py,sha256=HJLuhvEmllu_1KnFEJsYCIasaBJT0BV9Cn_4Y2QGPqg,2791
87
87
  pycityagent/cityagent/blocks/dispatcher.py,sha256=mEa1r3tRS3KI1BMZR_w_sbUGzOj6aUJuiUrsHv1n2n0,2943
88
88
  pycityagent/cityagent/blocks/needs_block.py,sha256=s8LikgtKORfo_Sw9SQ5_3biNPTof15QuUs4cDynXCyM,15332
@@ -97,9 +97,9 @@ pycityagent/cityagent/blocks/mobility_block.py,sha256=xWbARMfJ3-6fddrW3VOUKJrXfM
97
97
  pycityagent/survey/models.py,sha256=YE50UUt5qJ0O_lIUsSY6XFCGUTkJVNu_L1gAhaCJ2fs,3546
98
98
  pycityagent/survey/__init__.py,sha256=rxwou8U9KeFSP7rMzXtmtp2fVFZxK4Trzi-psx9LPIs,153
99
99
  pycityagent/survey/manager.py,sha256=S5IkwTdelsdtZETChRcfCEczzwSrry_Fly9MY4s3rbk,1681
100
- pycityagent-2.0.0a59.dist-info/RECORD,,
101
- pycityagent-2.0.0a59.dist-info/LICENSE,sha256=n2HPXiupinpyHMnIkbCf3OTYd3KMqbmldu1e7av0CAU,1084
102
- pycityagent-2.0.0a59.dist-info/WHEEL,sha256=ezfKMaDztqf77C8lvQ0NCnZxkTaOaKLprqJ8q932MhU,109
103
- pycityagent-2.0.0a59.dist-info/entry_points.txt,sha256=BZcne49AAIFv-hawxGnPbblea7X3MtAtoPyDX8L4OC4,132
104
- pycityagent-2.0.0a59.dist-info/top_level.txt,sha256=yOmeu6cSXmiUtScu53a3s0p7BGtLMaV0aff83EHCTic,43
105
- pycityagent-2.0.0a59.dist-info/METADATA,sha256=RMs-AgvrIOTGBqaoqMei0bF2eJRRqIwQn-r3UGBzwr0,9110
100
+ pycityagent-2.0.0a61.dist-info/RECORD,,
101
+ pycityagent-2.0.0a61.dist-info/LICENSE,sha256=n2HPXiupinpyHMnIkbCf3OTYd3KMqbmldu1e7av0CAU,1084
102
+ pycityagent-2.0.0a61.dist-info/WHEEL,sha256=ezfKMaDztqf77C8lvQ0NCnZxkTaOaKLprqJ8q932MhU,109
103
+ pycityagent-2.0.0a61.dist-info/entry_points.txt,sha256=BZcne49AAIFv-hawxGnPbblea7X3MtAtoPyDX8L4OC4,132
104
+ pycityagent-2.0.0a61.dist-info/top_level.txt,sha256=yOmeu6cSXmiUtScu53a3s0p7BGtLMaV0aff83EHCTic,43
105
+ pycityagent-2.0.0a61.dist-info/METADATA,sha256=hvkHrK65VERp64_mKCo6cwULjsAl_GTwsui2NCwOek4,9110