pycityagent 2.0.0a59__cp311-cp311-macosx_11_0_arm64.whl → 2.0.0a61__cp311-cp311-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.
- pycityagent/agent/agent.py +13 -19
- pycityagent/cityagent/message_intercept.py +8 -1
- pycityagent/pycityagent-sim +0 -0
- pycityagent/simulation/simulation.py +55 -17
- {pycityagent-2.0.0a59.dist-info → pycityagent-2.0.0a61.dist-info}/METADATA +1 -1
- {pycityagent-2.0.0a59.dist-info → pycityagent-2.0.0a61.dist-info}/RECORD +10 -10
- {pycityagent-2.0.0a59.dist-info → pycityagent-2.0.0a61.dist-info}/LICENSE +0 -0
- {pycityagent-2.0.0a59.dist-info → pycityagent-2.0.0a61.dist-info}/WHEEL +0 -0
- {pycityagent-2.0.0a59.dist-info → pycityagent-2.0.0a61.dist-info}/entry_points.txt +0 -0
- {pycityagent-2.0.0a59.dist-info → pycityagent-2.0.0a61.dist-info}/top_level.txt +0 -0
pycityagent/agent/agent.py
CHANGED
@@ -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
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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
|
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
|
pycityagent/pycityagent-sim
CHANGED
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,
|
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 ..
|
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 = {
|
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
|
-
#
|
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
|
-
|
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(
|
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 =
|
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.
|
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=
|
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=
|
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=
|
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=
|
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.
|
101
|
-
pycityagent-2.0.
|
102
|
-
pycityagent-2.0.
|
103
|
-
pycityagent-2.0.
|
104
|
-
pycityagent-2.0.
|
105
|
-
pycityagent-2.0.
|
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=NW1RskY9zow1Y68W-gXg0oZyBRAugI1JHywIzAIai5o,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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|