pycityagent 2.0.0a52__cp310-cp310-macosx_11_0_arm64.whl → 2.0.0a53__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.
- pycityagent/agent/agent.py +48 -62
- pycityagent/agent/agent_base.py +66 -53
- pycityagent/cityagent/bankagent.py +5 -7
- pycityagent/cityagent/blocks/__init__.py +0 -2
- pycityagent/cityagent/blocks/cognition_block.py +149 -172
- pycityagent/cityagent/blocks/economy_block.py +90 -129
- pycityagent/cityagent/blocks/mobility_block.py +56 -29
- pycityagent/cityagent/blocks/needs_block.py +163 -145
- pycityagent/cityagent/blocks/other_block.py +17 -9
- pycityagent/cityagent/blocks/plan_block.py +44 -56
- pycityagent/cityagent/blocks/social_block.py +70 -51
- pycityagent/cityagent/blocks/utils.py +2 -0
- pycityagent/cityagent/firmagent.py +6 -7
- pycityagent/cityagent/governmentagent.py +7 -9
- pycityagent/cityagent/memory_config.py +48 -48
- pycityagent/cityagent/nbsagent.py +6 -29
- pycityagent/cityagent/societyagent.py +204 -119
- pycityagent/environment/sim/client.py +10 -1
- pycityagent/environment/sim/clock_service.py +2 -2
- pycityagent/environment/sim/pause_service.py +61 -0
- pycityagent/environment/simulator.py +17 -12
- pycityagent/llm/embeddings.py +0 -24
- pycityagent/memory/faiss_query.py +29 -26
- pycityagent/memory/memory.py +720 -272
- pycityagent/pycityagent-sim +0 -0
- pycityagent/simulation/agentgroup.py +92 -99
- pycityagent/simulation/simulation.py +115 -40
- pycityagent/tools/tool.py +7 -9
- pycityagent/workflow/block.py +11 -4
- {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a53.dist-info}/METADATA +1 -1
- {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a53.dist-info}/RECORD +35 -35
- pycityagent/cityagent/blocks/time_block.py +0 -116
- {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a53.dist-info}/LICENSE +0 -0
- {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a53.dist-info}/WHEEL +0 -0
- {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a53.dist-info}/entry_points.txt +0 -0
- {pycityagent-2.0.0a52.dist-info → pycityagent-2.0.0a53.dist-info}/top_level.txt +0 -0
@@ -20,9 +20,8 @@ from ..cityagent import (BankAgent, FirmAgent, GovernmentAgent, NBSAgent,
|
|
20
20
|
from ..cityagent.initial import bind_agent_info, initialize_social_network
|
21
21
|
from ..environment.simulator import Simulator
|
22
22
|
from ..llm import SimpleEmbedding
|
23
|
-
from ..memory import Memory
|
24
23
|
from ..message.messager import Messager
|
25
|
-
from ..metrics import init_mlflow_connection
|
24
|
+
from ..metrics import MlflowClient, init_mlflow_connection
|
26
25
|
from ..survey import Survey
|
27
26
|
from ..utils import TO_UPDATE_EXP_INFO_KEYS_AND_TYPES
|
28
27
|
from .agentgroup import AgentGroup
|
@@ -39,6 +38,7 @@ class AgentSimulation:
|
|
39
38
|
config: dict,
|
40
39
|
agent_class: Union[None, type[Agent], list[type[Agent]]] = None,
|
41
40
|
agent_config_file: Optional[dict] = None,
|
41
|
+
metric_extractor: Optional[list[tuple[int, Callable]]] = None,
|
42
42
|
enable_economy: bool = True,
|
43
43
|
agent_prefix: str = "agent_",
|
44
44
|
exp_name: str = "default_experiment",
|
@@ -89,6 +89,8 @@ class AgentSimulation:
|
|
89
89
|
self._user_survey_topics: dict[str, str] = {}
|
90
90
|
self._user_interview_topics: dict[str, str] = {}
|
91
91
|
self._loop = asyncio.get_event_loop()
|
92
|
+
self._total_steps = 0
|
93
|
+
self._simulator_day = 0
|
92
94
|
# self._last_asyncio_pg_task = None # 将SQL写入的IO隐藏到计算任务后
|
93
95
|
|
94
96
|
self._messager = Messager.remote(
|
@@ -102,6 +104,7 @@ class AgentSimulation:
|
|
102
104
|
_storage_config: dict[str, Any] = config.get("storage", {})
|
103
105
|
if _storage_config is None:
|
104
106
|
_storage_config = {}
|
107
|
+
|
105
108
|
# avro
|
106
109
|
_avro_config: dict[str, Any] = _storage_config.get("avro", {})
|
107
110
|
self._enable_avro = _avro_config.get("enabled", False)
|
@@ -112,6 +115,27 @@ class AgentSimulation:
|
|
112
115
|
self._avro_path = Path(_avro_config["path"]) / f"{self.exp_id}"
|
113
116
|
self._avro_path.mkdir(parents=True, exist_ok=True)
|
114
117
|
|
118
|
+
# mlflow
|
119
|
+
_mlflow_config: dict[str, Any] = config.get("metric_request", {}).get("mlflow")
|
120
|
+
mlflow_run_id, _ = init_mlflow_connection(
|
121
|
+
config=_mlflow_config,
|
122
|
+
mlflow_run_name=f"EXP_{self.exp_name}_{1000*int(time.time())}",
|
123
|
+
experiment_name=self.exp_name,
|
124
|
+
)
|
125
|
+
if _mlflow_config:
|
126
|
+
logger.info(f"-----Creating Mlflow client...")
|
127
|
+
self.mlflow_client = MlflowClient(
|
128
|
+
config=_mlflow_config,
|
129
|
+
mlflow_run_name=f"EXP_{exp_name}_{1000*int(time.time())}",
|
130
|
+
experiment_name=exp_name,
|
131
|
+
run_id=mlflow_run_id,
|
132
|
+
)
|
133
|
+
self.metric_extractor = metric_extractor
|
134
|
+
else:
|
135
|
+
logger.warning("Mlflow is not enabled, NO MLFLOW STORAGE")
|
136
|
+
self.mlflow_client = None
|
137
|
+
self.metric_extractor = None
|
138
|
+
|
115
139
|
# pg
|
116
140
|
_pgsql_config: dict[str, Any] = _storage_config.get("pgsql", {})
|
117
141
|
self._enable_pgsql = _pgsql_config.get("enabled", False)
|
@@ -167,11 +191,11 @@ class AgentSimulation:
|
|
167
191
|
- workflow:
|
168
192
|
- list[Step]
|
169
193
|
- Step:
|
170
|
-
- type: str, "step", "run", "interview", "survey", "intervene"
|
194
|
+
- type: str, "step", "run", "interview", "survey", "intervene", "pause", "resume"
|
171
195
|
- day: int if type is "run", else None
|
172
|
-
-
|
196
|
+
- times: int if type is "step", else None
|
173
197
|
- description: Optional[str], description of the step
|
174
|
-
-
|
198
|
+
- func: Optional[Callable[AgentSimulation, None]], only used when type is "interview", "survey" and "intervene"
|
175
199
|
- logging_level: Optional[int]
|
176
200
|
- exp_name: Optional[str]
|
177
201
|
"""
|
@@ -224,10 +248,15 @@ class AgentSimulation:
|
|
224
248
|
if step["type"] == "run":
|
225
249
|
await simulation.run(step.get("day", 1))
|
226
250
|
elif step["type"] == "step":
|
227
|
-
|
228
|
-
|
251
|
+
times = step.get("times", 1)
|
252
|
+
for _ in range(times):
|
253
|
+
await simulation.step()
|
254
|
+
elif step["type"] == "pause":
|
255
|
+
await simulation.pause_simulator()
|
256
|
+
elif step["type"] == "resume":
|
257
|
+
await simulation.resume_simulator()
|
229
258
|
else:
|
230
|
-
await step["
|
259
|
+
await step["func"](simulation)
|
231
260
|
logger.info("Simulation finished")
|
232
261
|
|
233
262
|
@property
|
@@ -331,6 +360,12 @@ class AgentSimulation:
|
|
331
360
|
# 如果没有发生异常且状态不是错误,则更新为完成
|
332
361
|
await self._update_exp_status(2)
|
333
362
|
|
363
|
+
async def pause_simulator(self):
|
364
|
+
await self._simulator.pause()
|
365
|
+
|
366
|
+
async def resume_simulator(self):
|
367
|
+
await self._simulator.resume()
|
368
|
+
|
334
369
|
async def init_agents(
|
335
370
|
self,
|
336
371
|
agent_count: Union[int, list[int]],
|
@@ -353,12 +388,12 @@ class AgentSimulation:
|
|
353
388
|
raise ValueError("agent_class和agent_count的长度不一致")
|
354
389
|
|
355
390
|
if memory_config_func is None:
|
356
|
-
logger.warning(
|
357
|
-
"memory_config_func is None, using default memory config function"
|
358
|
-
)
|
359
391
|
memory_config_func = self.default_memory_config_func
|
360
392
|
|
361
393
|
elif not isinstance(memory_config_func, list):
|
394
|
+
logger.warning(
|
395
|
+
"memory_config_func is not a list, using specific memory config function"
|
396
|
+
)
|
362
397
|
memory_config_func = [memory_config_func]
|
363
398
|
|
364
399
|
if len(memory_config_func) != len(agent_count):
|
@@ -465,16 +500,6 @@ class AgentSimulation:
|
|
465
500
|
)
|
466
501
|
)
|
467
502
|
|
468
|
-
# 初始化mlflow连接
|
469
|
-
_mlflow_config = self.config.get("metric_request", {}).get("mlflow")
|
470
|
-
if _mlflow_config:
|
471
|
-
mlflow_run_id, _ = init_mlflow_connection(
|
472
|
-
config=_mlflow_config,
|
473
|
-
mlflow_run_name=f"EXP_{self.exp_name}_{1000*int(time.time())}",
|
474
|
-
experiment_name=self.exp_name,
|
475
|
-
)
|
476
|
-
else:
|
477
|
-
mlflow_run_id = None
|
478
503
|
# 建表
|
479
504
|
if self.enable_pgsql:
|
480
505
|
_num_workers = min(1, pg_sql_writers)
|
@@ -505,12 +530,10 @@ class AgentSimulation:
|
|
505
530
|
memory_config_function_group,
|
506
531
|
self.config,
|
507
532
|
self.exp_id,
|
508
|
-
self.exp_name,
|
509
533
|
self.enable_avro,
|
510
534
|
self.avro_path,
|
511
535
|
self.enable_pgsql,
|
512
536
|
_workers[i % _num_workers], # type:ignore
|
513
|
-
mlflow_run_id, # type:ignore
|
514
537
|
embedding_model,
|
515
538
|
self.logging_level,
|
516
539
|
config_file,
|
@@ -536,16 +559,20 @@ class AgentSimulation:
|
|
536
559
|
self._type2group[agent_type].append(group)
|
537
560
|
|
538
561
|
# 并行初始化所有组的agents
|
562
|
+
await self.resume_simulator()
|
539
563
|
init_tasks = []
|
540
564
|
for group in self._groups.values():
|
541
565
|
init_tasks.append(group.init_agents.remote())
|
542
566
|
ray.get(init_tasks)
|
567
|
+
await self.messager.connect.remote()
|
568
|
+
await self.messager.subscribe.remote([(f"exps/{self.exp_id}/user_payback", 1)], [self.exp_id])
|
569
|
+
await self.messager.start_listening.remote()
|
543
570
|
|
544
|
-
async def gather(self, content: str):
|
571
|
+
async def gather(self, content: str, target_agent_uuids: Optional[list[str]] = None):
|
545
572
|
"""收集智能体的特定信息"""
|
546
573
|
gather_tasks = []
|
547
574
|
for group in self._groups.values():
|
548
|
-
gather_tasks.append(group.gather.remote(content))
|
575
|
+
gather_tasks.append(group.gather.remote(content, target_agent_uuids))
|
549
576
|
return await asyncio.gather(*gather_tasks)
|
550
577
|
|
551
578
|
async def filter(
|
@@ -585,7 +612,6 @@ class AgentSimulation:
|
|
585
612
|
self, survey: Survey, agent_uuids: Optional[list[str]] = None
|
586
613
|
):
|
587
614
|
"""发送问卷"""
|
588
|
-
await self.messager.connect()
|
589
615
|
survey_dict = survey.to_dict()
|
590
616
|
if agent_uuids is None:
|
591
617
|
agent_uuids = self._agent_uuids
|
@@ -599,13 +625,20 @@ class AgentSimulation:
|
|
599
625
|
}
|
600
626
|
for uuid in agent_uuids:
|
601
627
|
topic = self._user_survey_topics[uuid]
|
602
|
-
await self.messager.send_message(topic, payload)
|
628
|
+
await self.messager.send_message.remote(topic, payload)
|
629
|
+
remain_payback = len(agent_uuids)
|
630
|
+
while True:
|
631
|
+
messages = await self.messager.fetch_messages.remote()
|
632
|
+
logger.info(f"Received {len(messages)} payback messages [survey]")
|
633
|
+
remain_payback -= len(messages)
|
634
|
+
if remain_payback <= 0:
|
635
|
+
break
|
636
|
+
await asyncio.sleep(3)
|
603
637
|
|
604
638
|
async def send_interview_message(
|
605
639
|
self, content: str, agent_uuids: Union[str, list[str]]
|
606
640
|
):
|
607
641
|
"""发送采访消息"""
|
608
|
-
await self.messager.connect()
|
609
642
|
_date_time = datetime.now(timezone.utc)
|
610
643
|
payload = {
|
611
644
|
"from": "none",
|
@@ -617,24 +650,67 @@ class AgentSimulation:
|
|
617
650
|
agent_uuids = [agent_uuids]
|
618
651
|
for uuid in agent_uuids:
|
619
652
|
topic = self._user_chat_topics[uuid]
|
620
|
-
await self.messager.send_message(topic, payload)
|
653
|
+
await self.messager.send_message.remote(topic, payload)
|
654
|
+
remain_payback = len(agent_uuids)
|
655
|
+
while True:
|
656
|
+
messages = await self.messager.fetch_messages.remote()
|
657
|
+
logger.info(f"Received {len(messages)} payback messages [interview]")
|
658
|
+
remain_payback -= len(messages)
|
659
|
+
if remain_payback <= 0:
|
660
|
+
break
|
661
|
+
await asyncio.sleep(3)
|
662
|
+
|
663
|
+
async def extract_metric(self, metric_extractor: list[Callable]):
|
664
|
+
"""提取指标"""
|
665
|
+
for metric_extractor in metric_extractor:
|
666
|
+
await metric_extractor(self)
|
621
667
|
|
622
668
|
async def step(self):
|
623
|
-
"""
|
669
|
+
"""Run one step, each agent execute one forward"""
|
624
670
|
try:
|
671
|
+
# check whether insert agents
|
672
|
+
simulator_day = await self._simulator.get_simulator_day()
|
673
|
+
print(f"simulator_day: {simulator_day}, self._simulator_day: {self._simulator_day}")
|
674
|
+
need_insert_agents = False
|
675
|
+
if simulator_day > self._simulator_day:
|
676
|
+
need_insert_agents = True
|
677
|
+
self._simulator_day = simulator_day
|
678
|
+
if need_insert_agents:
|
679
|
+
await self.resume_simulator()
|
680
|
+
insert_tasks = []
|
681
|
+
for group in self._groups.values():
|
682
|
+
insert_tasks.append(group.insert_agents.remote())
|
683
|
+
await asyncio.gather(*insert_tasks)
|
684
|
+
|
685
|
+
# step
|
625
686
|
tasks = []
|
626
687
|
for group in self._groups.values():
|
627
688
|
tasks.append(group.step.remote())
|
628
689
|
await asyncio.gather(*tasks)
|
690
|
+
# save
|
691
|
+
simulator_day = await self._simulator.get_simulator_day()
|
692
|
+
simulator_time = int(await self._simulator.get_time())
|
693
|
+
save_tasks = []
|
694
|
+
for group in self._groups.values():
|
695
|
+
save_tasks.append(group.save.remote(simulator_day, simulator_time))
|
696
|
+
await asyncio.gather(*save_tasks)
|
697
|
+
self._total_steps += 1
|
698
|
+
if self.metric_extractor is not None:
|
699
|
+
print(f"total_steps: {self._total_steps}, excute metric")
|
700
|
+
to_excute_metric = [
|
701
|
+
metric[1] for metric in self.metric_extractor if self._total_steps % metric[0] == 0
|
702
|
+
]
|
703
|
+
await self.extract_metric(to_excute_metric)
|
629
704
|
except Exception as e:
|
630
|
-
|
631
|
-
|
705
|
+
import traceback
|
706
|
+
logger.error(f"模拟器运行错误: {str(e)}\n{traceback.format_exc()}")
|
707
|
+
raise RuntimeError(str(e)) from e
|
632
708
|
|
633
709
|
async def run(
|
634
710
|
self,
|
635
711
|
day: int = 1,
|
636
712
|
):
|
637
|
-
"""
|
713
|
+
"""Run the simulation by days"""
|
638
714
|
try:
|
639
715
|
self._exp_info["num_day"] += day
|
640
716
|
await self._update_exp_status(1) # 更新状态为运行中
|
@@ -645,13 +721,12 @@ class AgentSimulation:
|
|
645
721
|
monitor_task = asyncio.create_task(self._monitor_exp_status(stop_event))
|
646
722
|
|
647
723
|
try:
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
await
|
654
|
-
|
724
|
+
end_time = await self._simulator.get_time() + day * 24 * 3600
|
725
|
+
while True:
|
726
|
+
current_time = await self._simulator.get_time()
|
727
|
+
if current_time >= end_time:
|
728
|
+
break
|
729
|
+
await self.step()
|
655
730
|
finally:
|
656
731
|
# 设置停止事件
|
657
732
|
stop_event.set()
|
pycityagent/tools/tool.py
CHANGED
@@ -119,7 +119,7 @@ class SencePOI(Tool):
|
|
119
119
|
if agent.memory is None or agent.simulator is None:
|
120
120
|
raise ValueError("Memory or Simulator is not set.")
|
121
121
|
if radius is None and category_prefix is None:
|
122
|
-
position = await agent.
|
122
|
+
position = await agent.status.get("position")
|
123
123
|
resp = []
|
124
124
|
for prefix in self.category_prefix:
|
125
125
|
resp += agent.simulator.map.query_pois(
|
@@ -146,17 +146,15 @@ class UpdateWithSimulator(Tool):
|
|
146
146
|
agent = self.agent
|
147
147
|
if agent._simulator is None:
|
148
148
|
return
|
149
|
-
if not agent._has_bound_to_simulator:
|
150
|
-
await agent._bind_to_simulator() # type: ignore
|
151
149
|
simulator = agent.simulator
|
152
|
-
|
153
|
-
person_id = await
|
150
|
+
status = agent.status
|
151
|
+
person_id = await status.get("id")
|
154
152
|
resp = await simulator.get_person(person_id)
|
155
153
|
resp_dict = resp["person"]
|
156
154
|
for k, v in resp_dict.get("motion", {}).items():
|
157
155
|
try:
|
158
|
-
await
|
159
|
-
await
|
156
|
+
await status.get(k)
|
157
|
+
await status.update(
|
160
158
|
k, v, mode="replace", protect_llm_read_only_fields=False
|
161
159
|
)
|
162
160
|
except KeyError as e:
|
@@ -183,9 +181,9 @@ class ResetAgentPosition(Tool):
|
|
183
181
|
s: Optional[float] = None,
|
184
182
|
):
|
185
183
|
agent = self.agent
|
186
|
-
|
184
|
+
status = agent.status
|
187
185
|
await agent.simulator.reset_person_position(
|
188
|
-
person_id=await
|
186
|
+
person_id=await status.get("id"),
|
189
187
|
aoi_id=aoi_id,
|
190
188
|
poi_id=poi_id,
|
191
189
|
lane_id=lane_id,
|
pycityagent/workflow/block.py
CHANGED
@@ -146,6 +146,7 @@ def trigger_class():
|
|
146
146
|
class Block:
|
147
147
|
configurable_fields: list[str] = []
|
148
148
|
default_values: dict[str, Any] = {}
|
149
|
+
fields_description: dict[str, str] = {}
|
149
150
|
|
150
151
|
def __init__(
|
151
152
|
self,
|
@@ -173,10 +174,16 @@ class Block:
|
|
173
174
|
|
174
175
|
@classmethod
|
175
176
|
def export_class_config(cls) -> dict[str, str]:
|
176
|
-
return
|
177
|
-
|
178
|
-
|
179
|
-
|
177
|
+
return (
|
178
|
+
{
|
179
|
+
field: cls.default_values.get(field, "default_value")
|
180
|
+
for field in cls.configurable_fields
|
181
|
+
},
|
182
|
+
{
|
183
|
+
field: cls.fields_description.get(field, "")
|
184
|
+
for field in cls.configurable_fields
|
185
|
+
}
|
186
|
+
)
|
180
187
|
|
181
188
|
@classmethod
|
182
189
|
def import_config(cls, config: dict[str, Union[str, dict]]) -> Block:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pycityagent
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.0a53
|
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,10 +1,10 @@
|
|
1
|
-
pycityagent-2.0.
|
2
|
-
pycityagent-2.0.
|
3
|
-
pycityagent-2.0.
|
4
|
-
pycityagent-2.0.
|
5
|
-
pycityagent-2.0.
|
6
|
-
pycityagent-2.0.
|
7
|
-
pycityagent/pycityagent-sim,sha256=
|
1
|
+
pycityagent-2.0.0a53.dist-info/RECORD,,
|
2
|
+
pycityagent-2.0.0a53.dist-info/LICENSE,sha256=n2HPXiupinpyHMnIkbCf3OTYd3KMqbmldu1e7av0CAU,1084
|
3
|
+
pycityagent-2.0.0a53.dist-info/WHEEL,sha256=ezfKMaDztqf77C8lvQ0NCnZxkTaOaKLprqJ8q932MhU,109
|
4
|
+
pycityagent-2.0.0a53.dist-info/entry_points.txt,sha256=BZcne49AAIFv-hawxGnPbblea7X3MtAtoPyDX8L4OC4,132
|
5
|
+
pycityagent-2.0.0a53.dist-info/top_level.txt,sha256=yOmeu6cSXmiUtScu53a3s0p7BGtLMaV0aff83EHCTic,43
|
6
|
+
pycityagent-2.0.0a53.dist-info/METADATA,sha256=7iSDzvMMlwpY7leIIjVm-3V7lZ92R0uHetTQlk0PCb0,9110
|
7
|
+
pycityagent/pycityagent-sim,sha256=1Nu-QYC0AuZyVWciGNa2XkYsUntbwAS15Bo7l-y6eok,35449490
|
8
8
|
pycityagent/__init__.py,sha256=PUKWTXc-xdMG7px8oTNclodsILUgypANj2Z647sY63k,808
|
9
9
|
pycityagent/pycityagent-ui,sha256=cHZjqtrQ4Fh4qtRahFNCNbT2DNHLmUexiDAa-72Z3RQ,40333378
|
10
10
|
pycityagent/metrics/mlflow_client.py,sha256=g_tHxWkWTDijtbGL74-HmiYzWVKb1y8-w12QrY9jL30,4449
|
@@ -13,24 +13,24 @@ pycityagent/metrics/utils/const.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
13
13
|
pycityagent/economy/__init__.py,sha256=aonY4WHnx-6EGJ4WKrx4S-2jAkYNLtqUA04jp6q8B7w,75
|
14
14
|
pycityagent/economy/econ_client.py,sha256=GuHK9ZBnhqW3Z7F8ViDJn_iN73yOBbbwFyJv1wLEBDk,12211
|
15
15
|
pycityagent/tools/__init__.py,sha256=XtdtGyWeFyK1YOUvWkykBWxemtmwQjWUIuuyU1-gosQ,261
|
16
|
-
pycityagent/tools/tool.py,sha256=
|
16
|
+
pycityagent/tools/tool.py,sha256=D-ESFlX7EESm5mcvs2zRlGEQTzXbVfQc8G7Vpz8TmAw,8651
|
17
17
|
pycityagent/llm/llmconfig.py,sha256=4Ylf4OFSBEFy8jrOneeX0HvPhWEaF5jGvy1HkXK08Ro,436
|
18
18
|
pycityagent/llm/__init__.py,sha256=iWs6FLgrbRVIiqOf4ILS89gkVCTvS7HFC3vG-MWuyko,205
|
19
19
|
pycityagent/llm/llm.py,sha256=owTYuXmnHZnvXaAvwiiyD511P3wpU3K04xZArhhiJF0,15700
|
20
|
-
pycityagent/llm/embeddings.py,sha256=
|
20
|
+
pycityagent/llm/embeddings.py,sha256=2_P4TWm3sJKFdGDx2Q1a2AEapFopDctIXsGuntvmP6E,6816
|
21
21
|
pycityagent/llm/utils.py,sha256=hoNPhvomb1u6lhFX0GctFipw74hVKb7bvUBDqwBzBYw,160
|
22
|
-
pycityagent/memory/memory.py,sha256=
|
22
|
+
pycityagent/memory/memory.py,sha256=suU6mZIYvGySQGyNrYiqdobuTgjSHyI_PahIeRVShiQ,34506
|
23
23
|
pycityagent/memory/profile.py,sha256=q8ZS9IBmHCg_X1GONUvXK85P6tCepTKQgXKuvuXYNXw,5203
|
24
24
|
pycityagent/memory/__init__.py,sha256=_Vfdo1HcLWsuuz34_i8e91nnLVYADpMlHHSVaB3xgIk,297
|
25
25
|
pycityagent/memory/memory_base.py,sha256=QG_j3BxZvkadFEeE3uBR_kjl_xcXD1aHUVs8GEF3d6w,5654
|
26
26
|
pycityagent/memory/self_define.py,sha256=vpZ6CIxR2grNXEIOScdpsSc59FBg0mOKelwQuTElbtQ,5200
|
27
27
|
pycityagent/memory/utils.py,sha256=oJWLdPeJy_jcdKcDTo9JAH9kDZhqjoQhhv_zT9qWC0w,877
|
28
28
|
pycityagent/memory/const.py,sha256=6zpJPJXWoH9-yf4RARYYff586agCoud9BRn7sPERB1g,932
|
29
|
-
pycityagent/memory/faiss_query.py,sha256=
|
29
|
+
pycityagent/memory/faiss_query.py,sha256=V3rIw6d1_xcpNqZBbAYz3qfjVNE7NfJ7xOS5SibPtVU,13180
|
30
30
|
pycityagent/memory/state.py,sha256=TYItiyDtehMEQaSBN7PpNrnNxdDM5jGppr9R9Ufv3kA,5134
|
31
|
-
pycityagent/simulation/simulation.py,sha256=
|
31
|
+
pycityagent/simulation/simulation.py,sha256=Fm6Y54gc4wAlVhMvqlUhbDRG0tKt6OpHdGsI8as9jqs,29662
|
32
32
|
pycityagent/simulation/__init__.py,sha256=P5czbcg2d8S0nbbnsQXFIhwzO4CennAhZM8OmKvAeYw,194
|
33
|
-
pycityagent/simulation/agentgroup.py,sha256=
|
33
|
+
pycityagent/simulation/agentgroup.py,sha256=F1LJq-4xq3E7NmhmBT8j9wsJuuRmU5rGFzNgeOCwOSI,29701
|
34
34
|
pycityagent/simulation/storage/pg.py,sha256=5itxKOkNPlOzN7z2_3oKU1ZK0uLTDugfld8ZkRbD69I,8407
|
35
35
|
pycityagent/message/__init__.py,sha256=TCjazxqb5DVwbTu1fF0sNvaH_EPXVuj2XQ0p6W-QCLU,55
|
36
36
|
pycityagent/message/messager.py,sha256=78K31EPKfC5IxbISc-Lc2babC7VOh9Vbe3c0sO-YDLA,3333
|
@@ -43,16 +43,16 @@ pycityagent/utils/parsers/__init__.py,sha256=AN2xgiPxszWK4rpX7zrqRsqNwfGF3WnCA5-
|
|
43
43
|
pycityagent/utils/parsers/code_block_parser.py,sha256=Cs2Z_hm9VfNCpPPll1TwteaJF-HAQPs-3RApsOekFm4,1173
|
44
44
|
pycityagent/utils/parsers/parser_base.py,sha256=KBKO4zLZPNdGjPAGqIus8LseZ8W3Tlt2y0QxqeCd25Q,1713
|
45
45
|
pycityagent/utils/parsers/json_parser.py,sha256=tjwyPluYfkWgsvLi0hzfJwFhO3L6yQfZMKza20HaGrY,2911
|
46
|
-
pycityagent/agent/agent_base.py,sha256=
|
46
|
+
pycityagent/agent/agent_base.py,sha256=FP2h3abIQ1Kp9qCzrzwa7tO82graDAWVg30HqYaQcPE,23620
|
47
47
|
pycityagent/agent/__init__.py,sha256=U20yKu9QwSqAx_PHk5JwipfODkDfxONtumVfnsKjWFg,180
|
48
|
-
pycityagent/agent/agent.py,sha256=
|
48
|
+
pycityagent/agent/agent.py,sha256=rYUC6idFb2dCRa7H7-0ZFPn4UB7MSTigHXOjNSK5B2Y,10702
|
49
49
|
pycityagent/cli/wrapper.py,sha256=2Tb52gOlEVgn11Ekt6ZkRXr_BGzte-EPyBKnR6g6hQ4,1143
|
50
50
|
pycityagent/workflow/__init__.py,sha256=H08Ko3eliZvuuCMajbEri-IP4-SeswYU6UjHBNA4Ze0,490
|
51
51
|
pycityagent/workflow/prompt.py,sha256=6jI0Rq54JLv3-IXqZLYug62vse10wTI83xvf4ZX42nk,2929
|
52
|
-
pycityagent/workflow/block.py,sha256=
|
52
|
+
pycityagent/workflow/block.py,sha256=REetWNdCF_fUGKVH-LWgDZ1lK2Bt0tJJ0kV20eWa4_A,9890
|
53
53
|
pycityagent/workflow/trigger.py,sha256=Df-MOBEDWBbM-v0dFLQLXteLsipymT4n8vqexmK2GiQ,5643
|
54
54
|
pycityagent/environment/__init__.py,sha256=awHxlOud-btWbk0FCS4RmGJ13W84oVCkbGfcrhKqihA,240
|
55
|
-
pycityagent/environment/simulator.py,sha256=
|
55
|
+
pycityagent/environment/simulator.py,sha256=pARK08PzqiAysy6VOR2KZAgEG7auVzt_Tecy5MBL55Q,12157
|
56
56
|
pycityagent/environment/message/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
57
|
pycityagent/environment/utils/port.py,sha256=3OM6kSUt3PxvDUOlgyiendBtETaWU8Mzk_8H0TzTmYg,295
|
58
58
|
pycityagent/environment/utils/grpc.py,sha256=6EJwKXXktIWb1NcUiJzIRmfrY0S03QAXXGcCDHqAT00,1998
|
@@ -66,38 +66,38 @@ pycityagent/environment/sence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
66
66
|
pycityagent/environment/sence/static.py,sha256=9s7jz8HitstTrk-GqpnVB26oPrjuTyNeL7hcoxjPhV4,29104
|
67
67
|
pycityagent/environment/sidecar/__init__.py,sha256=RFbOf40aYBP4WwRpFkua5tlRE_OtMcMNyp1Lew_aaAU,235
|
68
68
|
pycityagent/environment/sidecar/sidecarv2.py,sha256=beKlYZgt38EQbV1x6NWQo7xVXyB-5QHfbwJexyXu7Tg,3252
|
69
|
+
pycityagent/environment/sim/pause_service.py,sha256=DcAOVRxNkHGk4jyzFkxHMUPgp0Ck4mYHoPh6qxjhhLQ,1744
|
69
70
|
pycityagent/environment/sim/person_service.py,sha256=5r1F2Itn7dKJ2U4hSLovrk5p4qy-2n77MTAv_OlTIwA,10673
|
70
71
|
pycityagent/environment/sim/aoi_service.py,sha256=2UjvUTF4CW4E_L30IRcdwv6t_q1ZdXN3TTLOKSOaaXE,1230
|
71
72
|
pycityagent/environment/sim/sim_env.py,sha256=HI1LcS_FotDKQ6vBnx0e49prXSABOfA20aU9KM-ZkCY,4625
|
72
73
|
pycityagent/environment/sim/lane_service.py,sha256=N2dUe-3XuqqKLsNXt1k4NN8uV-J_ruo08yhaUd_hwOI,3916
|
73
|
-
pycityagent/environment/sim/client.py,sha256=
|
74
|
+
pycityagent/environment/sim/client.py,sha256=j0f8qjR1nIava4VkoZNEPqW5h08WPdcC5wzM9DP3tIs,3772
|
74
75
|
pycityagent/environment/sim/__init__.py,sha256=JVG6sSD2Hbohl1TtKjuQi7_M7tKMrFh9vl3QV3VA5O0,724
|
75
76
|
pycityagent/environment/sim/social_service.py,sha256=9EFJAwVdUuUQkNkFRn9qZRDfD1brh2fqkvasnXUEBhQ,2014
|
76
77
|
pycityagent/environment/sim/economy_services.py,sha256=xoc-1_H8JmQwJ24oWRS1fD-hGYtz2I-x6BOkQ4yENzU,7106
|
77
78
|
pycityagent/environment/sim/light_service.py,sha256=KVwt7ii_iLGA7gANZe3n6-4RiiPQt1w9H6ZOoizMI04,4242
|
78
|
-
pycityagent/environment/sim/clock_service.py,sha256=
|
79
|
+
pycityagent/environment/sim/clock_service.py,sha256=gBUujvX_vIFMKVfcLRyk1GcpRRL606opLhNjCYL7Gt4,1363
|
79
80
|
pycityagent/environment/sim/road_service.py,sha256=bKyn3_me0sGmaJVyF6eNeFbdU-9C1yWsa9L7pieDJzg,1285
|
80
81
|
pycityagent/environment/interact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
81
82
|
pycityagent/environment/interact/interact.py,sha256=ifxPPzuHeqLHIZ_6zvfXMoBOnBsXNIP4bYp7OJ7pnEQ,6588
|
82
|
-
pycityagent/cityagent/memory_config.py,sha256=
|
83
|
-
pycityagent/cityagent/bankagent.py,sha256=
|
83
|
+
pycityagent/cityagent/memory_config.py,sha256=yZdtfXz5VaASKRUiiotHXGVc8axCiCsTNGvoSkTWWgk,10861
|
84
|
+
pycityagent/cityagent/bankagent.py,sha256=lr4GEcqt-iwA7DXoDry0WXkV6benmdaAyLpswqSpKlY,2120
|
84
85
|
pycityagent/cityagent/__init__.py,sha256=gcBQ-a50XegFtjigQ7xDXRBZrywBKqifiQFSRnEF8gM,572
|
85
|
-
pycityagent/cityagent/firmagent.py,sha256=
|
86
|
-
pycityagent/cityagent/nbsagent.py,sha256=
|
86
|
+
pycityagent/cityagent/firmagent.py,sha256=UVlNN0lpa4cC4PZVqYzQhbc5VJ2oGsA1731mhbCjnR8,4109
|
87
|
+
pycityagent/cityagent/nbsagent.py,sha256=WIXW__6dZ5IrqBqDCjvGbrCshpXzuFRV3Ww6gkYw7p4,4387
|
87
88
|
pycityagent/cityagent/initial.py,sha256=7hgCt_tGdnVTXGfEQOn1GTW5dAs1b-ru_FwXxRLI6tM,4549
|
88
|
-
pycityagent/cityagent/societyagent.py,sha256=
|
89
|
-
pycityagent/cityagent/governmentagent.py,sha256=
|
89
|
+
pycityagent/cityagent/societyagent.py,sha256=QKzZecyN5npMi2IJlxei9MrJ1yJWJPCogXrNIP1VnFQ,19598
|
90
|
+
pycityagent/cityagent/governmentagent.py,sha256=HJLuhvEmllu_1KnFEJsYCIasaBJT0BV9Cn_4Y2QGPqg,2791
|
90
91
|
pycityagent/cityagent/blocks/dispatcher.py,sha256=mEa1r3tRS3KI1BMZR_w_sbUGzOj6aUJuiUrsHv1n2n0,2943
|
91
|
-
pycityagent/cityagent/blocks/needs_block.py,sha256=
|
92
|
-
pycityagent/cityagent/blocks/cognition_block.py,sha256=
|
93
|
-
pycityagent/cityagent/blocks/
|
94
|
-
pycityagent/cityagent/blocks/
|
95
|
-
pycityagent/cityagent/blocks/
|
96
|
-
pycityagent/cityagent/blocks/
|
97
|
-
pycityagent/cityagent/blocks/
|
98
|
-
pycityagent/cityagent/blocks/
|
99
|
-
pycityagent/cityagent/blocks/
|
100
|
-
pycityagent/cityagent/blocks/mobility_block.py,sha256=ZebloDhvZJYbV0YSWhAbnOLToiL-4fG7vKNq3kh37M4,10788
|
92
|
+
pycityagent/cityagent/blocks/needs_block.py,sha256=s8LikgtKORfo_Sw9SQ5_3biNPTof15QuUs4cDynXCyM,15332
|
93
|
+
pycityagent/cityagent/blocks/cognition_block.py,sha256=aeDIWbEmlcqmXyxeEiewXJyV0te3L6k95Kec12mUSM0,14954
|
94
|
+
pycityagent/cityagent/blocks/social_block.py,sha256=y46mPK9SLvcOHYB64l6qz5ZgT0dWNmX-C3Cusj_44mE,15540
|
95
|
+
pycityagent/cityagent/blocks/__init__.py,sha256=wydR0s-cCRWgdvQetkfQnD_PU8vC3eTmt2zntcb4fSA,452
|
96
|
+
pycityagent/cityagent/blocks/economy_block.py,sha256=m5B67cgGZ9nKWtrYeak5gxMoCoKlRbATAsXpFajYKyg,19129
|
97
|
+
pycityagent/cityagent/blocks/utils.py,sha256=8O5p1B8JlreIJTGXKAP03rTcn7MvFSR8qJ1_hhszboU,2065
|
98
|
+
pycityagent/cityagent/blocks/other_block.py,sha256=NnDwxQAO5XZ7Uxe-n3qtrfNItHlwFYk2MQsh2GYDKMQ,4338
|
99
|
+
pycityagent/cityagent/blocks/plan_block.py,sha256=Mtbc26xZjx-HpmBYZD12rVNK09WgDPCkwLseLiJ1mS0,10995
|
100
|
+
pycityagent/cityagent/blocks/mobility_block.py,sha256=xWbARMfJ3-6fddrW3VOUKJrXfMGmroiSN0B8t8lVYXA,12725
|
101
101
|
pycityagent/survey/models.py,sha256=YE50UUt5qJ0O_lIUsSY6XFCGUTkJVNu_L1gAhaCJ2fs,3546
|
102
102
|
pycityagent/survey/__init__.py,sha256=rxwou8U9KeFSP7rMzXtmtp2fVFZxK4Trzi-psx9LPIs,153
|
103
103
|
pycityagent/survey/manager.py,sha256=S5IkwTdelsdtZETChRcfCEczzwSrry_Fly9MY4s3rbk,1681
|
@@ -1,116 +0,0 @@
|
|
1
|
-
import asyncio
|
2
|
-
from datetime import datetime
|
3
|
-
import json
|
4
|
-
from pycityagent.workflow import Block
|
5
|
-
from pycityagent.llm.llm import LLM
|
6
|
-
from pycityagent.memory import Memory
|
7
|
-
from pycityagent.environment import Simulator
|
8
|
-
from pycityagent.workflow.prompt import FormatPrompt
|
9
|
-
from .utils import clean_json_response
|
10
|
-
|
11
|
-
class WorkReflectionBlock(Block):
|
12
|
-
"""
|
13
|
-
反馈工作感受
|
14
|
-
WorkReflectionBlock
|
15
|
-
"""
|
16
|
-
def __init__(self, llm: LLM, memory: Memory, simulator: Simulator):
|
17
|
-
super().__init__("WorkReflectionBlock", llm, memory, simulator)
|
18
|
-
self.description = "Feedback on work experience"
|
19
|
-
|
20
|
-
async def forward(self):
|
21
|
-
prompt = """
|
22
|
-
You are a {gender}, your consumption level is {consumption} and your education level is {education}.
|
23
|
-
Today's working experience:
|
24
|
-
{working_experience}
|
25
|
-
|
26
|
-
How is your feeling of work today?
|
27
|
-
|
28
|
-
Your answer should be one of the following:
|
29
|
-
- excellent
|
30
|
-
- good
|
31
|
-
- soso
|
32
|
-
- bad
|
33
|
-
- very bad
|
34
|
-
Answer in JSON format:
|
35
|
-
{{
|
36
|
-
"evaluation": "good",
|
37
|
-
}}
|
38
|
-
"""
|
39
|
-
prompt = FormatPrompt(prompt)
|
40
|
-
prompt.format(
|
41
|
-
**{key: await self.memory.get(key) for key in prompt.variables}
|
42
|
-
)
|
43
|
-
evaluation = await self.llm.atext_request(prompt.to_dialog(), timeout=300)
|
44
|
-
evaluation = clean_json_response(evaluation)
|
45
|
-
try:
|
46
|
-
evaluation = json.loads(evaluation)
|
47
|
-
except Exception as e:
|
48
|
-
evaluation = {'evaluation': 'soso'}
|
49
|
-
if evaluation['evaluation'] == 'excellent':
|
50
|
-
safe_improve = 0.2
|
51
|
-
elif evaluation['evaluation'] == 'good':
|
52
|
-
safe_improve = 0.1
|
53
|
-
elif evaluation['evaluation'] == 'soso':
|
54
|
-
safe_improve = 0.0
|
55
|
-
elif evaluation['evaluation'] == 'bad':
|
56
|
-
safe_improve = -0.1
|
57
|
-
elif evaluation['evaluation'] == 'very bad':
|
58
|
-
safe_improve = -0.2
|
59
|
-
else:
|
60
|
-
safe_improve = 0.0
|
61
|
-
|
62
|
-
needs = await self.memory.get("needs")
|
63
|
-
needs['safe'] += safe_improve
|
64
|
-
await self.memory.update("needs", needs)
|
65
|
-
await self.memory.update("working_experience", [])
|
66
|
-
return
|
67
|
-
|
68
|
-
|
69
|
-
class TimeBlock(Block):
|
70
|
-
"""固定时间trigger的工作流"""
|
71
|
-
def __init__(self, llm: LLM, memory: Memory, simulator: Simulator):
|
72
|
-
super().__init__(name="time_block", llm=llm, memory=memory, simulator=simulator)
|
73
|
-
self.blocks = []
|
74
|
-
self.work_reflection_block = WorkReflectionBlock(llm, memory, simulator)
|
75
|
-
self.blocks.append((self.work_reflection_block, self.str_to_time('23:59:59'))) # end of day
|
76
|
-
self.last_check_time = None
|
77
|
-
self.trigger_time = 0
|
78
|
-
self.token_consumption = 0
|
79
|
-
|
80
|
-
def str_to_time(self, time_str: str):
|
81
|
-
time_obj = datetime.strptime(time_str, '%H:%M:%S')
|
82
|
-
return time_obj.hour * 3600 + time_obj.minute * 60 + time_obj.second
|
83
|
-
|
84
|
-
async def blocks_to_trigger(self):
|
85
|
-
trigger_blocks = []
|
86
|
-
now_time = await self.simulator.get_time(format_time=True)
|
87
|
-
now_time = self.str_to_time(now_time)
|
88
|
-
if self.last_check_time is None:
|
89
|
-
self.last_check_time = now_time
|
90
|
-
else:
|
91
|
-
whether_cross_day = True if now_time < self.last_check_time else False
|
92
|
-
for block, trigger_time in self.blocks:
|
93
|
-
if whether_cross_day and trigger_time > self.last_check_time:
|
94
|
-
trigger_blocks.append(block)
|
95
|
-
elif not whether_cross_day and trigger_time > self.last_check_time and trigger_time <= now_time:
|
96
|
-
trigger_blocks.append(block)
|
97
|
-
self.last_check_time = now_time
|
98
|
-
return trigger_blocks
|
99
|
-
|
100
|
-
async def forward(self):
|
101
|
-
while True:
|
102
|
-
if len(self.blocks) == 0:
|
103
|
-
await asyncio.sleep(30)
|
104
|
-
continue
|
105
|
-
trigger_blocks = await self.blocks_to_trigger()
|
106
|
-
if len(trigger_blocks) == 0:
|
107
|
-
await asyncio.sleep(30)
|
108
|
-
continue
|
109
|
-
self.trigger_time += 1
|
110
|
-
consumption_start = self.llm.prompt_tokens_used + self.llm.completion_tokens_used
|
111
|
-
tasks = []
|
112
|
-
for block in trigger_blocks:
|
113
|
-
tasks.append(block.forward())
|
114
|
-
await asyncio.gather(*tasks)
|
115
|
-
consumption_end = self.llm.prompt_tokens_used + self.llm.completion_tokens_used
|
116
|
-
self.token_consumption += consumption_end - consumption_start
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|