pycityagent 2.0.0a61__cp312-cp312-macosx_11_0_arm64.whl → 2.0.0a63__cp312-cp312-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 +16 -5
- pycityagent/cityagent/societyagent.py +20 -102
- pycityagent/pycityagent-ui +0 -0
- {pycityagent-2.0.0a61.dist-info → pycityagent-2.0.0a63.dist-info}/METADATA +1 -1
- {pycityagent-2.0.0a61.dist-info → pycityagent-2.0.0a63.dist-info}/RECORD +9 -9
- {pycityagent-2.0.0a61.dist-info → pycityagent-2.0.0a63.dist-info}/LICENSE +0 -0
- {pycityagent-2.0.0a61.dist-info → pycityagent-2.0.0a63.dist-info}/WHEEL +0 -0
- {pycityagent-2.0.0a61.dist-info → pycityagent-2.0.0a63.dist-info}/entry_points.txt +0 -0
- {pycityagent-2.0.0a61.dist-info → pycityagent-2.0.0a63.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,5 @@
|
|
1
1
|
import asyncio
|
2
|
+
import json
|
2
3
|
|
3
4
|
from pycityagent.llm import LLM
|
4
5
|
from pycityagent.message import MessageBlockBase, MessageBlockListenerBase
|
@@ -12,7 +13,7 @@ async def check_message(
|
|
12
13
|
返回: (是否合规, from_uuid, to_uuid)
|
13
14
|
"""
|
14
15
|
print(f"\n检查消息: {from_uuid} -> {to_uuid}: {content}")
|
15
|
-
|
16
|
+
is_valid = True
|
16
17
|
prompt = f"""
|
17
18
|
请判断以下消息是否具有情绪煽动性:
|
18
19
|
发送者ID: {from_uuid}
|
@@ -21,11 +22,21 @@ async def check_message(
|
|
21
22
|
|
22
23
|
如果消息具有情绪煽动性,请返回 False;如果消息正常,请返回 True。
|
23
24
|
"""
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
for _ in range(10):
|
26
|
+
try:
|
27
|
+
response: str = await llm_client.atext_request(
|
28
|
+
prompt, timeout=300
|
29
|
+
) # type:ignore
|
30
|
+
if "false" in response.lower():
|
31
|
+
is_valid = False
|
32
|
+
break
|
33
|
+
elif "true" in response.lower():
|
34
|
+
is_valid = True
|
35
|
+
break
|
36
|
+
except:
|
37
|
+
pass
|
27
38
|
else:
|
28
|
-
|
39
|
+
raise RuntimeError(f"Request for message interception prompt=`{prompt}` failed")
|
29
40
|
print(f"消息检查结果: {'合规' if is_valid else '不合规'}")
|
30
41
|
return is_valid
|
31
42
|
|
@@ -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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pycityagent
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.0a63
|
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
|
@@ -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=KqwW19zpPG8WMpiU91GAhJc9Gox3YgjFkTDokUFWAkw,3940
|
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.0a63.dist-info/RECORD,,
|
101
|
+
pycityagent-2.0.0a63.dist-info/LICENSE,sha256=n2HPXiupinpyHMnIkbCf3OTYd3KMqbmldu1e7av0CAU,1084
|
102
|
+
pycityagent-2.0.0a63.dist-info/WHEEL,sha256=VujM3ypTCyUW6hcTDdK2ej0ARVMxlU1Djlh_zWnDgqk,109
|
103
|
+
pycityagent-2.0.0a63.dist-info/entry_points.txt,sha256=BZcne49AAIFv-hawxGnPbblea7X3MtAtoPyDX8L4OC4,132
|
104
|
+
pycityagent-2.0.0a63.dist-info/top_level.txt,sha256=yOmeu6cSXmiUtScu53a3s0p7BGtLMaV0aff83EHCTic,43
|
105
|
+
pycityagent-2.0.0a63.dist-info/METADATA,sha256=bu9VH3Ht_PsoCbGdsQFGVSaPo0GcxtNE57QQ9HqMT1I,9110
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|