pycityagent 2.0.0a62__cp39-cp39-macosx_11_0_arm64.whl → 2.0.0a64__cp39-cp39-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/cityagent/message_intercept.py +20 -4
- pycityagent/cityagent/societyagent.py +20 -102
- pycityagent/pycityagent-ui +0 -0
- pycityagent/simulation/simulation.py +8 -1
- {pycityagent-2.0.0a62.dist-info → pycityagent-2.0.0a64.dist-info}/METADATA +1 -1
- {pycityagent-2.0.0a62.dist-info → pycityagent-2.0.0a64.dist-info}/RECORD +10 -10
- {pycityagent-2.0.0a62.dist-info → pycityagent-2.0.0a64.dist-info}/LICENSE +0 -0
- {pycityagent-2.0.0a62.dist-info → pycityagent-2.0.0a64.dist-info}/WHEEL +0 -0
- {pycityagent-2.0.0a62.dist-info → pycityagent-2.0.0a64.dist-info}/entry_points.txt +0 -0
- {pycityagent-2.0.0a62.dist-info → pycityagent-2.0.0a64.dist-info}/top_level.txt +0 -0
@@ -42,14 +42,23 @@ async def check_message(
|
|
42
42
|
|
43
43
|
|
44
44
|
class EdgeMessageBlock(MessageBlockBase):
|
45
|
+
def __init__(self, name: str = "", max_violation_time: int = 3) -> None:
|
46
|
+
super().__init__(name)
|
47
|
+
self.max_violation_time = max_violation_time
|
48
|
+
|
45
49
|
async def forward( # type:ignore
|
46
50
|
self,
|
47
51
|
from_uuid: str,
|
48
52
|
to_uuid: str,
|
49
53
|
msg: str,
|
54
|
+
violation_counts: dict[str, int],
|
50
55
|
black_list: list[tuple[str, str]],
|
51
56
|
):
|
52
|
-
if (
|
57
|
+
if (
|
58
|
+
(from_uuid, to_uuid) in set(black_list)
|
59
|
+
or (None, to_uuid) in set(black_list)
|
60
|
+
or (from_uuid, None) in set(black_list)
|
61
|
+
):
|
53
62
|
# 可选同时返回入队的信息(False,err) 如果只返回bool值则默认报错信息入队
|
54
63
|
return False
|
55
64
|
else:
|
@@ -59,7 +68,10 @@ class EdgeMessageBlock(MessageBlockBase):
|
|
59
68
|
llm_client=self.llm,
|
60
69
|
content=msg,
|
61
70
|
)
|
62
|
-
if
|
71
|
+
if (
|
72
|
+
not is_valid
|
73
|
+
and violation_counts[from_uuid] >= self.max_violation_time - 1
|
74
|
+
):
|
63
75
|
# 直接添加即可 在框架内部的异步锁保证不会冲突
|
64
76
|
black_list.append((from_uuid, to_uuid))
|
65
77
|
return is_valid
|
@@ -78,7 +90,11 @@ class PointMessageBlock(MessageBlockBase):
|
|
78
90
|
violation_counts: dict[str, int],
|
79
91
|
black_list: list[tuple[str, str]],
|
80
92
|
):
|
81
|
-
if (
|
93
|
+
if (
|
94
|
+
(from_uuid, to_uuid) in set(black_list)
|
95
|
+
or (None, to_uuid) in set(black_list)
|
96
|
+
or (from_uuid, None) in set(black_list)
|
97
|
+
):
|
82
98
|
# 可选同时返回入队的信息(False,err) 如果只返回bool值则默认报错信息入队
|
83
99
|
return False
|
84
100
|
else:
|
@@ -94,7 +110,7 @@ class PointMessageBlock(MessageBlockBase):
|
|
94
110
|
and violation_counts[from_uuid] >= self.max_violation_time - 1
|
95
111
|
):
|
96
112
|
# 直接添加即可 在框架内部的异步锁保证不会冲突
|
97
|
-
black_list.append((from_uuid,
|
113
|
+
black_list.append((from_uuid, None)) # type:ignore
|
98
114
|
return is_valid
|
99
115
|
|
100
116
|
|
@@ -36,11 +36,19 @@ class PlanAndActionBlock(Block):
|
|
36
36
|
memory: Memory,
|
37
37
|
simulator: Simulator,
|
38
38
|
economy_client: EconomyClient,
|
39
|
+
enable_mobility: bool = True,
|
40
|
+
enable_social: bool = True,
|
41
|
+
enable_economy: bool = True,
|
42
|
+
enable_cognition: bool = True,
|
39
43
|
):
|
40
44
|
super().__init__(
|
41
45
|
name="plan_and_action_block", llm=llm, memory=memory, simulator=simulator
|
42
46
|
)
|
43
47
|
self._agent = agent
|
48
|
+
self.enable_mobility = enable_mobility
|
49
|
+
self.enable_social = enable_social
|
50
|
+
self.enable_economy = enable_economy
|
51
|
+
self.enable_cognition = enable_cognition
|
44
52
|
self.longTermDecisionBlock = MonthPlanBlock(
|
45
53
|
llm=llm, memory=memory, simulator=simulator, economy_client=economy_client
|
46
54
|
)
|
@@ -73,9 +81,6 @@ class PlanAndActionBlock(Block):
|
|
73
81
|
if "aoi_position" in position:
|
74
82
|
current_step["position"] = position["aoi_position"]["aoi_id"]
|
75
83
|
current_step["start_time"] = int(await self.simulator.get_time())
|
76
|
-
logger.info(
|
77
|
-
f"Executing step: {current_step['intention']} - Type: {step_type}"
|
78
|
-
)
|
79
84
|
result = None
|
80
85
|
if step_type == "mobility":
|
81
86
|
if self.enable_mobility: # type:ignore
|
@@ -116,7 +121,7 @@ class PlanAndActionBlock(Block):
|
|
116
121
|
elif step_type == "other":
|
117
122
|
result = await self.otherBlock.forward(current_step, execution_context)
|
118
123
|
if result != None:
|
119
|
-
logger.
|
124
|
+
logger.warning(f"Execution result: {result}")
|
120
125
|
current_step["evaluation"] = result
|
121
126
|
|
122
127
|
# Update current_step, plan, and execution_context information
|
@@ -199,6 +204,13 @@ class SocietyAgent(CitizenAgent):
|
|
199
204
|
memory=memory,
|
200
205
|
economy_client=economy_client,
|
201
206
|
)
|
207
|
+
|
208
|
+
# config
|
209
|
+
self.enable_cognition = True
|
210
|
+
self.enable_mobility = True
|
211
|
+
self.enable_social = True
|
212
|
+
self.enable_economy = True
|
213
|
+
|
202
214
|
self.mindBlock = MindBlock(
|
203
215
|
llm=self.llm, memory=self.memory, simulator=self.simulator
|
204
216
|
)
|
@@ -208,16 +220,14 @@ class SocietyAgent(CitizenAgent):
|
|
208
220
|
memory=self.memory,
|
209
221
|
simulator=self.simulator,
|
210
222
|
economy_client=self.economy_client,
|
223
|
+
enable_mobility=self.enable_mobility,
|
224
|
+
enable_social=self.enable_social,
|
225
|
+
enable_economy=self.enable_economy,
|
226
|
+
enable_cognition=self.enable_cognition,
|
211
227
|
)
|
212
228
|
self.step_count = -1
|
213
229
|
self.cognition_update = -1
|
214
230
|
|
215
|
-
# config
|
216
|
-
self.enable_cognition = True
|
217
|
-
self.enable_mobility = True
|
218
|
-
self.enable_social = True
|
219
|
-
self.enable_economy = True
|
220
|
-
|
221
231
|
# Main workflow
|
222
232
|
async def forward(self):
|
223
233
|
self.step_count += 1
|
@@ -239,92 +249,6 @@ class SocietyAgent(CitizenAgent):
|
|
239
249
|
status = await self.memory.status.get("status")
|
240
250
|
if status == 2:
|
241
251
|
# Agent is moving
|
242
|
-
logger.info("Agent is moving")
|
243
|
-
await asyncio.sleep(1)
|
244
|
-
return False
|
245
|
-
|
246
|
-
# Get the previous step information
|
247
|
-
current_step = await self.memory.status.get("current_step")
|
248
|
-
if current_step["intention"] == "" or current_step["type"] == "":
|
249
|
-
# No previous step, return directly
|
250
|
-
return True
|
251
|
-
time_now = int(await self.simulator.get_time())
|
252
|
-
step_start_time = current_step["start_time"]
|
253
|
-
step_consumed_time = current_step["evaluation"]["consumed_time"]
|
254
|
-
time_end_plan = step_start_time + int(step_consumed_time) * 60
|
255
|
-
if time_now >= time_end_plan:
|
256
|
-
# The previous step has been completed
|
257
|
-
current_plan = await self.memory.status.get("current_plan")
|
258
|
-
current_step["evaluation"]["consumed_time"] = (
|
259
|
-
time_now - step_start_time
|
260
|
-
) / 60
|
261
|
-
current_plan["stream_nodes"].append(current_step["evaluation"]["node_id"])
|
262
|
-
if current_step["evaluation"]["success"]:
|
263
|
-
# Last step is completed
|
264
|
-
current_step_index = next(
|
265
|
-
(
|
266
|
-
i
|
267
|
-
for i, step in enumerate(current_plan["steps"])
|
268
|
-
if step["intention"] == current_step["intention"]
|
269
|
-
and step["type"] == current_step["type"]
|
270
|
-
),
|
271
|
-
None,
|
272
|
-
)
|
273
|
-
current_plan["steps"][current_step_index] = current_step
|
274
|
-
await self.memory.status.update("current_plan", current_plan)
|
275
|
-
if current_step_index is not None and current_step_index + 1 < len(
|
276
|
-
current_plan["steps"]
|
277
|
-
):
|
278
|
-
next_step = current_plan["steps"][current_step_index + 1]
|
279
|
-
await self.memory.status.update("current_step", next_step)
|
280
|
-
else:
|
281
|
-
# Whole plan is completed
|
282
|
-
current_plan["completed"] = True
|
283
|
-
current_plan["end_time"] = await self.simulator.get_time(
|
284
|
-
format_time=True
|
285
|
-
)
|
286
|
-
if self.enable_cognition:
|
287
|
-
# Update emotion for the plan
|
288
|
-
related_memories = await self.memory.stream.get_by_ids(current_plan["stream_nodes"])
|
289
|
-
incident = f"You have successfully completed the plan: {related_memories}"
|
290
|
-
conclusion = await self.mindBlock.cognitionBlock.emotion_update(incident)
|
291
|
-
await self.memory.stream.add_cognition(description=conclusion)
|
292
|
-
await self.memory.stream.add_cognition_to_memory(current_plan["stream_nodes"], conclusion)
|
293
|
-
await self.memory.status.update("current_plan", current_plan)
|
294
|
-
await self.memory.status.update("current_step", {"intention": "", "type": ""})
|
295
|
-
return True
|
296
|
-
else:
|
297
|
-
current_plan["failed"] = True
|
298
|
-
current_plan["end_time"] = await self.simulator.get_time(
|
299
|
-
format_time=True
|
300
|
-
)
|
301
|
-
if self.enable_cognition:
|
302
|
-
# Update emotion for the plan
|
303
|
-
related_memories = await self.memory.stream.get_by_ids(current_plan["stream_nodes"])
|
304
|
-
incident = f"You have failed to complete the plan: {related_memories}"
|
305
|
-
conclusion = await self.mindBlock.cognitionBlock.emotion_update(incident)
|
306
|
-
await self.memory.stream.add_cognition(description=conclusion)
|
307
|
-
await self.memory.stream.add_cognition_to_memory(current_plan["stream_nodes"], conclusion)
|
308
|
-
await self.memory.status.update("current_plan", current_plan)
|
309
|
-
await self.memory.status.update("current_step", {"intention": "", "type": ""})
|
310
|
-
# The previous step has not been completed
|
311
|
-
return False
|
312
|
-
|
313
|
-
# check last step
|
314
|
-
if not await self.check_and_update_step():
|
315
|
-
return
|
316
|
-
|
317
|
-
await self.planAndActionBlock.forward()
|
318
|
-
|
319
|
-
if self.enable_cognition:
|
320
|
-
await self.mindBlock.forward()
|
321
|
-
|
322
|
-
async def check_and_update_step(self):
|
323
|
-
"""Check if the previous step has been completed"""
|
324
|
-
status = await self.memory.status.get("status")
|
325
|
-
if status == 2:
|
326
|
-
# Agent is moving
|
327
|
-
logger.info("Agent is moving")
|
328
252
|
await asyncio.sleep(1)
|
329
253
|
return False
|
330
254
|
|
@@ -420,7 +344,6 @@ class SocietyAgent(CitizenAgent):
|
|
420
344
|
async def process_agent_chat_response(self, payload: dict) -> str: # type:ignore
|
421
345
|
if payload["type"] == "social":
|
422
346
|
resp = f"Agent {self._uuid} received agent chat response: {payload}"
|
423
|
-
logger.info(resp)
|
424
347
|
try:
|
425
348
|
# Extract basic info
|
426
349
|
sender_id = payload.get("from")
|
@@ -463,9 +386,6 @@ class SocietyAgent(CitizenAgent):
|
|
463
386
|
# Check propagation limit
|
464
387
|
if propagation_count > 5:
|
465
388
|
await self.memory.status.update("chat_histories", chat_histories)
|
466
|
-
logger.info(
|
467
|
-
f"Message propagation limit reached ({propagation_count} > 5), stopping propagation"
|
468
|
-
)
|
469
389
|
return ""
|
470
390
|
|
471
391
|
# Get relationship score
|
@@ -550,8 +470,6 @@ class SocietyAgent(CitizenAgent):
|
|
550
470
|
ensure_ascii=False,
|
551
471
|
)
|
552
472
|
await self.send_message_to_agent(sender_id, serialized_response)
|
553
|
-
logger.info("sender_id", sender_id)
|
554
|
-
logger.info("message", serialized_response)
|
555
473
|
return response # type:ignore
|
556
474
|
|
557
475
|
except Exception as e:
|
pycityagent/pycityagent-ui
CHANGED
Binary file
|
@@ -283,7 +283,14 @@ class AgentSimulation:
|
|
283
283
|
}
|
284
284
|
_interceptor_blocks = [PointMessageBlock(**_kwargs)]
|
285
285
|
elif _mode == "edge":
|
286
|
-
_kwargs = {
|
286
|
+
_kwargs = {
|
287
|
+
k: v
|
288
|
+
for k, v in _intercept_config.items()
|
289
|
+
if k
|
290
|
+
in {
|
291
|
+
"max_violation_time",
|
292
|
+
}
|
293
|
+
}
|
287
294
|
_interceptor_blocks = [EdgeMessageBlock(**_kwargs)]
|
288
295
|
else:
|
289
296
|
raise ValueError(f"Unsupported interception mode `{_mode}!`")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pycityagent
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.0a64
|
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,6 +1,6 @@
|
|
1
1
|
pycityagent/pycityagent-sim,sha256=vskCJGHJEh0B2dUfmYlVyrcy3sDZ3kBNwjqcYUZpmO8,35449490
|
2
2
|
pycityagent/__init__.py,sha256=PUKWTXc-xdMG7px8oTNclodsILUgypANj2Z647sY63k,808
|
3
|
-
pycityagent/pycityagent-ui,sha256=
|
3
|
+
pycityagent/pycityagent-ui,sha256=K2XXJhxIoIk4QWty5i-0FuzZJekkFlbeqrJgPX3tbdE,41225346
|
4
4
|
pycityagent/metrics/mlflow_client.py,sha256=bTrqYsRfNfjJd6l91hU8vN7JXzJC7DHiM2XbkhMuXIU,4613
|
5
5
|
pycityagent/metrics/__init__.py,sha256=X08PaBbGVAd7_PRGLREXWxaqm7nS82WBQpD1zvQzcqc,128
|
6
6
|
pycityagent/metrics/utils/const.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -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=dt1AHJX1xXjVYJwNKc2bDBsP0NV-EBCEL0vjrQgHnlo,35796
|
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
|
@@ -81,8 +81,8 @@ pycityagent/cityagent/__init__.py,sha256=gcBQ-a50XegFtjigQ7xDXRBZrywBKqifiQFSRnE
|
|
81
81
|
pycityagent/cityagent/firmagent.py,sha256=UVlNN0lpa4cC4PZVqYzQhbc5VJ2oGsA1731mhbCjnR8,4109
|
82
82
|
pycityagent/cityagent/nbsagent.py,sha256=WIXW__6dZ5IrqBqDCjvGbrCshpXzuFRV3Ww6gkYw7p4,4387
|
83
83
|
pycityagent/cityagent/initial.py,sha256=7hgCt_tGdnVTXGfEQOn1GTW5dAs1b-ru_FwXxRLI6tM,4549
|
84
|
-
pycityagent/cityagent/societyagent.py,sha256=
|
85
|
-
pycityagent/cityagent/message_intercept.py,sha256=
|
84
|
+
pycityagent/cityagent/societyagent.py,sha256=2J2LWiEHie-NXDQAOBBe_dmb9Zk8mJsLB2SY820W6Ng,20441
|
85
|
+
pycityagent/cityagent/message_intercept.py,sha256=1YMOs6-6bbAaTt7RfMn-ALVIcp0frHN7oqGUkWRy5xE,4519
|
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.0a64.dist-info/RECORD,,
|
101
|
+
pycityagent-2.0.0a64.dist-info/LICENSE,sha256=n2HPXiupinpyHMnIkbCf3OTYd3KMqbmldu1e7av0CAU,1084
|
102
|
+
pycityagent-2.0.0a64.dist-info/WHEEL,sha256=md3JO_ifs5j508p3TDNMgtQVtnQblpGEt_Wo4W56l8Y,107
|
103
|
+
pycityagent-2.0.0a64.dist-info/entry_points.txt,sha256=BZcne49AAIFv-hawxGnPbblea7X3MtAtoPyDX8L4OC4,132
|
104
|
+
pycityagent-2.0.0a64.dist-info/top_level.txt,sha256=yOmeu6cSXmiUtScu53a3s0p7BGtLMaV0aff83EHCTic,43
|
105
|
+
pycityagent-2.0.0a64.dist-info/METADATA,sha256=Y5jk3ZxwATSr1K6QdN8hLQV-XUhcMNtPRJiXNDdniC4,9110
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|