pycityagent 2.0.0a12__py3-none-any.whl → 2.0.0a13__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.
- pycityagent/agent.py +39 -8
- pycityagent/simulation/agentgroup.py +38 -40
- {pycityagent-2.0.0a12.dist-info → pycityagent-2.0.0a13.dist-info}/METADATA +1 -1
- {pycityagent-2.0.0a12.dist-info → pycityagent-2.0.0a13.dist-info}/RECORD +5 -5
- {pycityagent-2.0.0a12.dist-info → pycityagent-2.0.0a13.dist-info}/WHEEL +0 -0
pycityagent/agent.py
CHANGED
@@ -427,7 +427,9 @@ class InstitutionAgent(Agent):
|
|
427
427
|
simulator,
|
428
428
|
memory,
|
429
429
|
)
|
430
|
-
|
430
|
+
# 添加响应收集器
|
431
|
+
self._gather_responses: Dict[str, asyncio.Future] = {}
|
432
|
+
|
431
433
|
async def bind_to_simulator(self):
|
432
434
|
await self._bind_to_economy()
|
433
435
|
|
@@ -514,18 +516,47 @@ class InstitutionAgent(Agent):
|
|
514
516
|
|
515
517
|
async def handle_gather_message(self, payload: dict):
|
516
518
|
"""处理收到的消息,识别发送者"""
|
517
|
-
# 从消息中解析发送者 ID 和消息内容
|
518
519
|
content = payload["content"]
|
519
520
|
sender_id = payload["from"]
|
520
|
-
|
521
|
-
|
522
|
-
)
|
523
|
-
|
524
|
-
|
525
|
-
|
521
|
+
|
522
|
+
# 将响应存储到对应的Future中
|
523
|
+
response_key = str(sender_id)
|
524
|
+
if response_key in self._gather_responses:
|
525
|
+
self._gather_responses[response_key].set_result({
|
526
|
+
"from": sender_id,
|
527
|
+
"content": content,
|
528
|
+
})
|
529
|
+
|
530
|
+
async def gather_messages(self, agent_ids: list[UUID], target: str) -> List[dict]:
|
531
|
+
"""从多个智能体收集消息
|
532
|
+
|
533
|
+
Args:
|
534
|
+
agent_ids: 目标智能体ID列表
|
535
|
+
target: 要收集的信息类型
|
536
|
+
|
537
|
+
Returns:
|
538
|
+
List[dict]: 收集到的所有响应
|
539
|
+
"""
|
540
|
+
# 为每个agent创建Future
|
541
|
+
futures = {}
|
542
|
+
for agent_id in agent_ids:
|
543
|
+
response_key = str(agent_id)
|
544
|
+
futures[response_key] = asyncio.Future()
|
545
|
+
self._gather_responses[response_key] = futures[response_key]
|
546
|
+
|
547
|
+
# 发送gather请求
|
526
548
|
payload = {
|
527
549
|
"from": self._uuid,
|
528
550
|
"target": target,
|
529
551
|
}
|
530
552
|
for agent_id in agent_ids:
|
531
553
|
await self._send_message(agent_id, payload, "gather")
|
554
|
+
|
555
|
+
try:
|
556
|
+
# 等待所有响应
|
557
|
+
responses = await asyncio.gather(*futures.values())
|
558
|
+
return responses
|
559
|
+
finally:
|
560
|
+
# 清理Future
|
561
|
+
for key in futures:
|
562
|
+
self._gather_responses.pop(key, None)
|
@@ -71,7 +71,8 @@ class AgentGroup:
|
|
71
71
|
topic = f"exps/{self.exp_id}/agents/{agent._uuid}/gather"
|
72
72
|
await self.messager.subscribe(topic, agent)
|
73
73
|
self.initialized = True
|
74
|
-
|
74
|
+
self.message_dispatch_task = asyncio.create_task(self.message_dispatch())
|
75
|
+
|
75
76
|
async def gather(self, content: str):
|
76
77
|
results = {}
|
77
78
|
for agent in self.agents:
|
@@ -82,49 +83,46 @@ class AgentGroup:
|
|
82
83
|
agent = self.id2agent[target_agent_uuid]
|
83
84
|
await agent.memory.update(target_key, content)
|
84
85
|
|
86
|
+
async def message_dispatch(self):
|
87
|
+
while True:
|
88
|
+
if not self.messager.is_connected():
|
89
|
+
logging.warning("Messager is not connected. Skipping message processing.")
|
90
|
+
|
91
|
+
# Step 1: 获取消息
|
92
|
+
messages = await self.messager.fetch_messages()
|
93
|
+
logging.info(f"Group {self._uuid} received {len(messages)} messages")
|
94
|
+
|
95
|
+
# Step 2: 分发消息到对应的 Agent
|
96
|
+
for message in messages:
|
97
|
+
topic = message.topic.value
|
98
|
+
payload = message.payload
|
99
|
+
|
100
|
+
# 添加解码步骤,将bytes转换为str
|
101
|
+
if isinstance(payload, bytes):
|
102
|
+
payload = payload.decode("utf-8")
|
103
|
+
payload = json.loads(payload)
|
104
|
+
|
105
|
+
# 提取 agent_id(主题格式为 "exps/{exp_id}/agents/{agent_uuid}/{topic_type}")
|
106
|
+
_, _, _, agent_uuid, topic_type = topic.strip("/").split("/")
|
107
|
+
|
108
|
+
if uuid.UUID(agent_uuid) in self.id2agent:
|
109
|
+
agent = self.id2agent[uuid.UUID(agent_uuid)]
|
110
|
+
# topic_type: agent-chat, user-chat, user-survey, gather
|
111
|
+
if topic_type == "agent-chat":
|
112
|
+
await agent.handle_agent_chat_message(payload)
|
113
|
+
elif topic_type == "user-chat":
|
114
|
+
await agent.handle_user_chat_message(payload)
|
115
|
+
elif topic_type == "user-survey":
|
116
|
+
await agent.handle_user_survey_message(payload)
|
117
|
+
elif topic_type == "gather":
|
118
|
+
await agent.handle_gather_message(payload)
|
119
|
+
|
120
|
+
await asyncio.sleep(1)
|
121
|
+
|
85
122
|
async def step(self):
|
86
123
|
if not self.initialized:
|
87
124
|
await self.init_agents()
|
88
125
|
|
89
|
-
# Step 1: 如果 Messager 无法连接,则跳过消息接收
|
90
|
-
if not self.messager.is_connected():
|
91
|
-
logging.warning("Messager is not connected. Skipping message processing.")
|
92
|
-
# 跳过接收和分发消息
|
93
|
-
tasks = [agent.run() for agent in self.agents]
|
94
|
-
await asyncio.gather(*tasks)
|
95
|
-
return
|
96
|
-
|
97
|
-
# Step 2: 从 Messager 获取消息
|
98
|
-
messages = await self.messager.fetch_messages()
|
99
|
-
|
100
|
-
logging.info(f"Group {self._uuid} received {len(messages)} messages")
|
101
|
-
|
102
|
-
# Step 3: 分发消息到对应的 Agent
|
103
|
-
for message in messages:
|
104
|
-
topic = message.topic.value
|
105
|
-
payload = message.payload
|
106
|
-
|
107
|
-
# 添加解码步骤,将bytes转换为str
|
108
|
-
if isinstance(payload, bytes):
|
109
|
-
payload = payload.decode("utf-8")
|
110
|
-
payload = json.loads(payload)
|
111
|
-
|
112
|
-
# 提取 agent_id(主题格式为 "exps/{exp_id}/agents/{agent_uuid}/{topic_type}")
|
113
|
-
_, _, _, agent_uuid, topic_type = topic.strip("/").split("/")
|
114
|
-
|
115
|
-
if uuid.UUID(agent_uuid) in self.id2agent:
|
116
|
-
agent = self.id2agent[uuid.UUID(agent_uuid)]
|
117
|
-
# topic_type: agent-chat, user-chat, user-survey, gather
|
118
|
-
if topic_type == "agent-chat":
|
119
|
-
await agent.handle_agent_chat_message(payload)
|
120
|
-
elif topic_type == "user-chat":
|
121
|
-
await agent.handle_user_chat_message(payload)
|
122
|
-
elif topic_type == "user-survey":
|
123
|
-
await agent.handle_user_survey_message(payload)
|
124
|
-
elif topic_type == "gather":
|
125
|
-
await agent.handle_gather_message(payload)
|
126
|
-
|
127
|
-
# Step 4: 调用每个 Agent 的运行逻辑
|
128
126
|
tasks = [agent.run() for agent in self.agents]
|
129
127
|
await asyncio.gather(*tasks)
|
130
128
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
pycityagent/__init__.py,sha256=n56bWkAUEcvjDsb7LcJpaGjlrriSKPnR0yBhwRfEYBA,212
|
2
|
-
pycityagent/agent.py,sha256=
|
2
|
+
pycityagent/agent.py,sha256=7BCHK5OH1TvW16JLiYR0iWAiWGBuP4eJsiGU1y7exbY,18417
|
3
3
|
pycityagent/economy/__init__.py,sha256=aonY4WHnx-6EGJ4WKrx4S-2jAkYNLtqUA04jp6q8B7w,75
|
4
4
|
pycityagent/economy/econ_client.py,sha256=qQb_kZneEXGBRaS_y5Jdoi95I8GyjKEsDSC4s6V6R7w,10829
|
5
5
|
pycityagent/environment/__init__.py,sha256=awHxlOud-btWbk0FCS4RmGJ13W84oVCkbGfcrhKqihA,240
|
@@ -46,7 +46,7 @@ pycityagent/memory/utils.py,sha256=wLNlNlZ-AY9VB8kbUIy0UQSYh26FOQABbhmKQkit5o8,8
|
|
46
46
|
pycityagent/message/__init__.py,sha256=TCjazxqb5DVwbTu1fF0sNvaH_EPXVuj2XQ0p6W-QCLU,55
|
47
47
|
pycityagent/message/messager.py,sha256=Iv4pK83JvHAQSZyGNACryPBey2wRoiok3Hb1eIwHbww,2506
|
48
48
|
pycityagent/simulation/__init__.py,sha256=jYaqaNpzM5M_e_ykISS_M-mIyYdzJXJWhgpfBpA6l5k,111
|
49
|
-
pycityagent/simulation/agentgroup.py,sha256=
|
49
|
+
pycityagent/simulation/agentgroup.py,sha256=fM93ydsuZ_w8YVnHnX1tWskWVYmt6sztKjzgDXcg1Xw,6106
|
50
50
|
pycityagent/simulation/interview.py,sha256=S2uv8MFCB4-u_4Q202VFoPJOIleqpKK9Piju0BDSb_0,1158
|
51
51
|
pycityagent/simulation/simulation.py,sha256=4BHavfSHPM81Y5Su-MzzBYM0sR9cHRk4YOv-VkRkzrA,11595
|
52
52
|
pycityagent/simulation/survey/__init__.py,sha256=rxwou8U9KeFSP7rMzXtmtp2fVFZxK4Trzi-psx9LPIs,153
|
@@ -65,6 +65,6 @@ pycityagent/workflow/block.py,sha256=6EmiRMLdOZC1wMlmLMIjfrp9TuiI7Gw4s3nnXVMbrnw
|
|
65
65
|
pycityagent/workflow/prompt.py,sha256=tY69nDO8fgYfF_dOA-iceR8pAhkYmCqoox8uRPqEuGY,2956
|
66
66
|
pycityagent/workflow/tool.py,sha256=wD9WZ5rma6HCKugtHTwbShNE0f-Rjlwvn_1be3fCAsk,6682
|
67
67
|
pycityagent/workflow/trigger.py,sha256=t5X_i0WtL32bipZSsq_E3UUyYYudYLxQUpvxbgClp2s,5683
|
68
|
-
pycityagent-2.0.
|
69
|
-
pycityagent-2.0.
|
70
|
-
pycityagent-2.0.
|
68
|
+
pycityagent-2.0.0a13.dist-info/METADATA,sha256=MdIVm_sOeGM99wtIKpcDEt6zt3Gp-loHI5MxGTz_6og,7622
|
69
|
+
pycityagent-2.0.0a13.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
70
|
+
pycityagent-2.0.0a13.dist-info/RECORD,,
|
File without changes
|