pycityagent 2.0.0a81__cp311-cp311-macosx_11_0_arm64.whl → 2.0.0a82__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 +4 -0
- pycityagent/cityagent/bankagent.py +4 -3
- pycityagent/cityagent/blocks/cognition_block.py +11 -6
- pycityagent/cityagent/firmagent.py +4 -2
- pycityagent/cityagent/initial.py +2 -0
- pycityagent/cityagent/memory_config.py +2 -0
- pycityagent/cityagent/nbsagent.py +21 -6
- pycityagent/economy/econ_client.py +205 -62
- pycityagent/environment/sim/sim_env.py +0 -3
- pycityagent/environment/simulator.py +1 -1
- pycityagent/llm/llm.py +12 -0
- pycityagent/pycityagent-sim +0 -0
- pycityagent/simulation/simulation.py +1 -1
- {pycityagent-2.0.0a81.dist-info → pycityagent-2.0.0a82.dist-info}/METADATA +2 -2
- {pycityagent-2.0.0a81.dist-info → pycityagent-2.0.0a82.dist-info}/RECORD +19 -19
- {pycityagent-2.0.0a81.dist-info → pycityagent-2.0.0a82.dist-info}/LICENSE +0 -0
- {pycityagent-2.0.0a81.dist-info → pycityagent-2.0.0a82.dist-info}/WHEEL +0 -0
- {pycityagent-2.0.0a81.dist-info → pycityagent-2.0.0a82.dist-info}/entry_points.txt +0 -0
- {pycityagent-2.0.0a81.dist-info → pycityagent-2.0.0a82.dist-info}/top_level.txt +0 -0
pycityagent/agent/agent.py
CHANGED
@@ -331,6 +331,8 @@ class InstitutionAgent(Agent):
|
|
331
331
|
working_hours = await _status.get("working_hours", [])
|
332
332
|
employees = await _status.get("employees", [])
|
333
333
|
citizens = await _status.get("citizens", [])
|
334
|
+
demand = await _status.get("demand", 0)
|
335
|
+
sales = await _status.get("sales", 0)
|
334
336
|
await self._economy_client.add_orgs(
|
335
337
|
{
|
336
338
|
"id": _id,
|
@@ -354,6 +356,8 @@ class InstitutionAgent(Agent):
|
|
354
356
|
"working_hours": working_hours,
|
355
357
|
"employees": employees,
|
356
358
|
"citizens": citizens,
|
359
|
+
"demand": demand,
|
360
|
+
"sales": sales,
|
357
361
|
}
|
358
362
|
)
|
359
363
|
except Exception as e:
|
@@ -81,12 +81,12 @@ class BankAgent(InstitutionAgent):
|
|
81
81
|
|
82
82
|
async def forward(self):
|
83
83
|
if await self.month_trigger():
|
84
|
+
print("bank forward")
|
84
85
|
interest_rate = await self.economy_client.get(self._agent_id, 'interest_rate')
|
85
86
|
citizens = await self.economy_client.get(self._agent_id, 'citizens')
|
86
87
|
for citizen in citizens:
|
87
|
-
wealth = self.economy_client.get(citizen, 'currency')
|
88
|
+
wealth = await self.economy_client.get(citizen, 'currency')
|
88
89
|
await self.economy_client.add_delta_value(citizen, 'currency', interest_rate*wealth)
|
89
|
-
|
90
90
|
nbs_id = await self.economy_client.get_org_entity_ids(economyv2.ORG_TYPE_NBS)
|
91
91
|
nbs_id = nbs_id[0]
|
92
92
|
prices = await self.economy_client.get(nbs_id, 'prices')
|
@@ -101,4 +101,5 @@ class BankAgent(InstitutionAgent):
|
|
101
101
|
interest_rate = natural_interest_rate + target_inflation + inflation_coeff * (avg_inflation - target_inflation)
|
102
102
|
else:
|
103
103
|
interest_rate = natural_interest_rate + target_inflation
|
104
|
-
await self.economy_client.update(self._agent_id, 'interest_rate', interest_rate)
|
104
|
+
await self.economy_client.update(self._agent_id, 'interest_rate', interest_rate)
|
105
|
+
print("bank forward end")
|
@@ -36,7 +36,7 @@ class CognitionBlock(Block):
|
|
36
36
|
def __init__(self, llm: LLM, memory: Memory, simulator: Simulator):
|
37
37
|
super().__init__("CognitionBlock", llm=llm, memory=memory, simulator=simulator)
|
38
38
|
self.top_k = 20
|
39
|
-
|
39
|
+
self.last_check_time = 0
|
40
40
|
async def set_status(self, status):
|
41
41
|
for key in status:
|
42
42
|
await self.memory.status.update(key, status[key])
|
@@ -75,7 +75,7 @@ class CognitionBlock(Block):
|
|
75
75
|
In the following 21 words, I have chosen {emotion_types} to represent your current status:
|
76
76
|
Joy, Distress, Resentment, Pity, Hope, Fear, Satisfaction, Relief, Disappointment, Pride, Admiration, Shame, Reproach, Liking, Disliking, Gratitude, Anger, Gratification, Remorse, Love, Hate.
|
77
77
|
"""
|
78
|
-
incident_str = await self.memory.stream.
|
78
|
+
incident_str = await self.memory.stream.search(query=topic, top_k=self.top_k)
|
79
79
|
if incident_str:
|
80
80
|
incident_prompt = "Today, these incidents happened:"
|
81
81
|
incident_prompt += incident_str
|
@@ -202,17 +202,22 @@ class CognitionBlock(Block):
|
|
202
202
|
|
203
203
|
return thought
|
204
204
|
|
205
|
-
async def
|
206
|
-
"""Cognition -
|
205
|
+
async def cross_day(self):
|
206
|
+
"""Cognition - cross day workflow"""
|
207
207
|
time = await self.simulator.get_simulator_second_from_start_of_day()
|
208
|
-
if
|
208
|
+
if self.last_check_time == 0:
|
209
|
+
self.last_check_time = time
|
210
|
+
return False
|
211
|
+
if time < self.last_check_time:
|
212
|
+
self.last_check_time = time
|
209
213
|
return True
|
214
|
+
self.last_check_time = time
|
210
215
|
return False
|
211
216
|
|
212
217
|
async def forward(self):
|
213
218
|
"""Cognition workflow: Daily update"""
|
214
219
|
# cognition update: thought and attitude
|
215
|
-
if await self.
|
220
|
+
if await self.cross_day():
|
216
221
|
await self.thought_update()
|
217
222
|
await self.attitude_update()
|
218
223
|
|
@@ -66,12 +66,14 @@ class FirmAgent(InstitutionAgent):
|
|
66
66
|
|
67
67
|
async def forward(self):
|
68
68
|
if await self.month_trigger():
|
69
|
+
print("firm forward")
|
69
70
|
employees = await self.economy_client.get(self._agent_id, "employees")
|
70
71
|
total_demand = await self.economy_client.get(self._agent_id, "demand")
|
71
72
|
goods_consumption = await self.economy_client.get(self._agent_id, "sales")
|
72
73
|
last_inventory = goods_consumption + await self.economy_client.get(self._agent_id, "inventory")
|
73
74
|
max_change_rate = (total_demand - last_inventory) / (max(total_demand, last_inventory) + 1e-8)
|
74
|
-
skills =
|
75
|
+
skills = await self.economy_client.get(employees, "skill")
|
76
|
+
skills = np.array(skills)
|
75
77
|
skill_change_ratio = np.random.uniform(0, max_change_rate*self.max_wage_inflation)
|
76
78
|
await self.economy_client.update(employees, "skill", list(np.maximum(skills*(1 + skill_change_ratio), 1)))
|
77
79
|
price = await self.economy_client.get(self._agent_id, "price")
|
@@ -89,6 +91,6 @@ class FirmAgent(InstitutionAgent):
|
|
89
91
|
1,
|
90
92
|
),
|
91
93
|
)
|
92
|
-
|
93
94
|
await self.economy_client.update(self._agent_id, 'demand', 0)
|
94
95
|
await self.economy_client.update(self._agent_id, 'sales', 0)
|
96
|
+
print("firm forward end")
|
pycityagent/cityagent/initial.py
CHANGED
@@ -141,5 +141,7 @@ async def bind_agent_info(simulation):
|
|
141
141
|
await simulation.economy_update(uid2agent[government_uuid], "citizens", citizen_agent_ids)
|
142
142
|
for bank_uuid in bank_uuids:
|
143
143
|
await simulation.economy_update(uid2agent[bank_uuid], "citizens", citizen_agent_ids)
|
144
|
+
for nbs_uuid in nbs_uuids:
|
145
|
+
await simulation.economy_update(uid2agent[nbs_uuid], "citizens", citizen_agent_ids)
|
144
146
|
logger.info("Agent info binding completed!")
|
145
147
|
|
@@ -235,6 +235,8 @@ def memory_config_firm():
|
|
235
235
|
"real_gdp": (list, []),
|
236
236
|
"unemployment": (list, []),
|
237
237
|
"wages": (list, []),
|
238
|
+
"demand": (int, 0),
|
239
|
+
"sales": (int, 0),
|
238
240
|
"prices": (list, [float(np.mean(agent_skills))]),
|
239
241
|
"working_hours": (list, []),
|
240
242
|
"depression": (list, []),
|
@@ -70,26 +70,37 @@ class NBSAgent(InstitutionAgent):
|
|
70
70
|
|
71
71
|
async def forward(self):
|
72
72
|
if await self.month_trigger():
|
73
|
-
|
73
|
+
print("nbs forward")
|
74
|
+
await self.economy_client.calculate_real_gdp(self._agent_id)
|
74
75
|
citizens_uuid = await self.memory.status.get("citizens")
|
75
76
|
citizens = await self.economy_client.get(self._agent_id, "citizens")
|
76
77
|
work_propensity = await self.gather_messages(citizens_uuid, "work_propensity")
|
77
|
-
|
78
|
+
if sum(work_propensity) == 0.0:
|
79
|
+
working_hours = 0.0
|
80
|
+
else:
|
81
|
+
working_hours = np.mean(work_propensity) * self.num_labor_hours
|
78
82
|
await self.economy_client.update(
|
79
83
|
self._agent_id, "working_hours", [working_hours], mode="merge"
|
80
84
|
)
|
81
85
|
firms_id = await self.economy_client.get_org_entity_ids(economyv2.ORG_TYPE_FIRM)
|
82
86
|
prices = await self.economy_client.get(firms_id, "price")
|
87
|
+
|
83
88
|
await self.economy_client.update(
|
84
89
|
self._agent_id, "prices", [float(np.mean(prices))], mode="merge"
|
85
90
|
)
|
86
91
|
depression = await self.gather_messages(citizens_uuid, "depression")
|
87
|
-
depression
|
92
|
+
if sum(depression) == 0.0:
|
93
|
+
depression = 0.0
|
94
|
+
else:
|
95
|
+
depression = np.mean(depression)
|
88
96
|
await self.economy_client.update(
|
89
97
|
self._agent_id, "depression", [depression], mode="merge"
|
90
98
|
)
|
91
99
|
consumption_currency = await self.economy_client.get(citizens, "consumption")
|
92
|
-
consumption_currency
|
100
|
+
if sum(consumption_currency) == 0.0:
|
101
|
+
consumption_currency = 0.0
|
102
|
+
else:
|
103
|
+
consumption_currency = np.mean(consumption_currency)
|
93
104
|
await self.economy_client.update(
|
94
105
|
self._agent_id,
|
95
106
|
"consumption_currency",
|
@@ -97,7 +108,11 @@ class NBSAgent(InstitutionAgent):
|
|
97
108
|
mode="merge",
|
98
109
|
)
|
99
110
|
income_currency = await self.economy_client.get(citizens, "income")
|
100
|
-
income_currency
|
111
|
+
if sum(income_currency) == 0.0:
|
112
|
+
income_currency = 0.0
|
113
|
+
else:
|
114
|
+
income_currency = np.mean(income_currency)
|
101
115
|
await self.economy_client.update(
|
102
116
|
self._agent_id, "income_currency", [income_currency], mode="merge"
|
103
|
-
)
|
117
|
+
)
|
118
|
+
print("nbs forward end")
|
@@ -149,131 +149,255 @@ class EconomyClient:
|
|
149
149
|
self._agent_ids = agent_ids
|
150
150
|
self._org_ids = org_ids
|
151
151
|
|
152
|
-
async def get_agent(self, id: int) ->
|
152
|
+
async def get_agent(self, id: Union[list[int], int]) -> economyv2.Agent:
|
153
153
|
"""
|
154
154
|
Get agent by id
|
155
155
|
|
156
156
|
- **Args**:
|
157
|
-
- `id` (`int`): The id of the agent.
|
157
|
+
- `id` (`Union[list[int], int]`): The id of the agent.
|
158
158
|
|
159
159
|
- **Returns**:
|
160
160
|
- `economyv2.Agent`: The agent object.
|
161
161
|
"""
|
162
162
|
start_time = time.time()
|
163
|
-
log = {
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
163
|
+
log = {
|
164
|
+
"req": "get_agent",
|
165
|
+
"start_time": start_time,
|
166
|
+
"consumption": 0
|
167
|
+
}
|
168
|
+
if isinstance(id, list):
|
169
|
+
agents = await self._aio_stub.BatchGet(
|
170
|
+
org_service.BatchGetRequest(
|
171
|
+
ids=id,
|
172
|
+
type="agent"
|
173
|
+
)
|
174
|
+
)
|
175
|
+
agents = MessageToDict(agents)["agents"]
|
176
|
+
agent_dicts = [camel_to_snake(agent) for agent in agents]
|
177
|
+
log["consumption"] = time.time() - start_time
|
178
|
+
self._log_list.append(log)
|
179
|
+
return agent_dicts
|
180
|
+
else:
|
181
|
+
agent = await self._aio_stub.GetAgent(
|
182
|
+
org_service.GetAgentRequest(
|
183
|
+
agent_id=id
|
184
|
+
)
|
185
|
+
)
|
186
|
+
agent_dict = MessageToDict(agent)["agent"]
|
187
|
+
log["consumption"] = time.time() - start_time
|
188
|
+
self._log_list.append(log)
|
189
|
+
return camel_to_snake(agent_dict)
|
169
190
|
|
170
|
-
async def get_org(self, id: int) ->
|
191
|
+
async def get_org(self, id: Union[list[int], int]) -> economyv2.Org:
|
171
192
|
"""
|
172
193
|
Get org by id
|
173
194
|
|
174
195
|
- **Args**:
|
175
|
-
- `id` (`int`): The id of the org.
|
196
|
+
- `id` (`Union[list[int], int]`): The id of the org.
|
176
197
|
|
177
198
|
- **Returns**:
|
178
199
|
- `economyv2.Org`: The org object.
|
179
200
|
"""
|
180
201
|
start_time = time.time()
|
181
|
-
log = {
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
202
|
+
log = {
|
203
|
+
"req": "get_org",
|
204
|
+
"start_time": start_time,
|
205
|
+
"consumption": 0
|
206
|
+
}
|
207
|
+
if isinstance(id, list):
|
208
|
+
orgs = await self._aio_stub.BatchGet(
|
209
|
+
org_service.BatchGetRequest(
|
210
|
+
ids=id,
|
211
|
+
type="org"
|
212
|
+
)
|
213
|
+
)
|
214
|
+
orgs = MessageToDict(orgs)["orgs"]
|
215
|
+
org_dicts = [camel_to_snake(org) for org in orgs]
|
216
|
+
log["consumption"] = time.time() - start_time
|
217
|
+
self._log_list.append(log)
|
218
|
+
return org_dicts
|
219
|
+
else:
|
220
|
+
org = await self._aio_stub.GetOrg(
|
221
|
+
org_service.GetOrgRequest(
|
222
|
+
org_id=id
|
223
|
+
)
|
224
|
+
)
|
225
|
+
org_dict = MessageToDict(org)["org"]
|
226
|
+
log["consumption"] = time.time() - start_time
|
227
|
+
self._log_list.append(log)
|
228
|
+
return camel_to_snake(org_dict)
|
187
229
|
|
188
230
|
async def get(
|
189
231
|
self,
|
190
|
-
id: int,
|
232
|
+
id: Union[list[int], int],
|
191
233
|
key: str,
|
192
234
|
) -> Any:
|
193
235
|
"""
|
194
236
|
Get specific value
|
195
237
|
|
196
238
|
- **Args**:
|
197
|
-
- `id` (`int`): The id of `Org` or `Agent`.
|
239
|
+
- `id` (`Union[list[int], int]`): The id of `Org` or `Agent`.
|
198
240
|
- `key` (`str`): The attribute to fetch.
|
199
241
|
|
200
242
|
- **Returns**:
|
201
243
|
- Any
|
202
244
|
"""
|
203
245
|
start_time = time.time()
|
204
|
-
log = {
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
246
|
+
log = {
|
247
|
+
"req": "get",
|
248
|
+
"start_time": start_time,
|
249
|
+
"consumption": 0
|
250
|
+
}
|
251
|
+
if isinstance(id, list):
|
252
|
+
requests = "Org" if id[0] in self._org_ids else "Agent"
|
253
|
+
if requests == "Org":
|
254
|
+
response = await self.get_org(id)
|
255
|
+
else:
|
256
|
+
response = await self.get_agent(id)
|
257
|
+
results = []
|
258
|
+
for res in response:
|
259
|
+
results.append(res[key])
|
260
|
+
log["consumption"] = time.time() - start_time
|
261
|
+
self._log_list.append(log)
|
262
|
+
return results
|
210
263
|
else:
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
264
|
+
if id not in self._agent_ids and id not in self._org_ids:
|
265
|
+
raise ValueError(f"Invalid id {id}, this id does not exist!")
|
266
|
+
request_type = "Org" if id in self._org_ids else "Agent"
|
267
|
+
if request_type == "Org":
|
268
|
+
response = await self.get_org(id)
|
269
|
+
else:
|
270
|
+
response = await self.get_agent(id)
|
271
|
+
log["consumption"] = time.time() - start_time
|
272
|
+
self._log_list.append(log)
|
273
|
+
return response[key]
|
274
|
+
|
275
|
+
def _merge(self, original_value, key, value):
|
276
|
+
try:
|
277
|
+
orig_value = original_value[key]
|
278
|
+
_orig_type = type(orig_value)
|
279
|
+
_new_type = type(value)
|
280
|
+
except:
|
281
|
+
type_ = type(value)
|
282
|
+
_orig_type = type_
|
283
|
+
_new_type = type_
|
284
|
+
orig_value = type_()
|
285
|
+
if _orig_type != _new_type:
|
286
|
+
logger.debug(
|
287
|
+
f"Inconsistent type of original value {_orig_type.__name__} and to-update value {_new_type.__name__}"
|
288
|
+
)
|
289
|
+
else:
|
290
|
+
if isinstance(orig_value, set):
|
291
|
+
orig_value.update(set(value))
|
292
|
+
original_value[key] = orig_value
|
293
|
+
elif isinstance(orig_value, dict):
|
294
|
+
orig_value.update(dict(value))
|
295
|
+
original_value[key] = orig_value
|
296
|
+
elif isinstance(orig_value, list):
|
297
|
+
orig_value.extend(list(value))
|
298
|
+
original_value[key] = orig_value
|
299
|
+
else:
|
300
|
+
logger.warning(
|
301
|
+
f"Type of {type(orig_value)} does not support mode `merge`, using `replace` instead!"
|
302
|
+
)
|
215
303
|
|
216
304
|
async def update(
|
217
305
|
self,
|
218
|
-
id: int,
|
306
|
+
id: Union[list[int], int],
|
219
307
|
key: str,
|
220
|
-
value: Any,
|
308
|
+
value: Union[Any, list[Any]],
|
221
309
|
mode: Union[Literal["replace"], Literal["merge"]] = "replace",
|
222
310
|
) -> Any:
|
223
311
|
"""
|
224
312
|
Update key-value pair
|
225
313
|
|
226
314
|
- **Args**:
|
227
|
-
- `id` (`int`): The id of `Org` or `Agent`.
|
315
|
+
- `id` (`Union[list[int], int]`): The id of `Org` or `Agent`.
|
228
316
|
- `key` (`str`): The attribute to update.
|
317
|
+
- `value` (`Union[Any, list[Any]]`): The value to update.
|
229
318
|
- `mode` (Union[Literal["replace"], Literal["merge"]], optional): Update mode. Defaults to "replace".
|
230
319
|
|
231
320
|
- **Returns**:
|
232
321
|
- Any
|
233
322
|
"""
|
234
323
|
start_time = time.time()
|
235
|
-
log = {
|
236
|
-
|
237
|
-
|
238
|
-
|
324
|
+
log = {
|
325
|
+
"req": "update",
|
326
|
+
"start_time": start_time,
|
327
|
+
"consumption": 0
|
328
|
+
}
|
329
|
+
if isinstance(id, list):
|
330
|
+
if not isinstance(value, list):
|
331
|
+
raise ValueError(f"Invalid value, the value must be a list!")
|
332
|
+
if len(id) != len(value):
|
333
|
+
raise ValueError(f"Invalid ids and values, the length of ids and values must be the same!")
|
334
|
+
request_type = "Org" if id[0] in self._org_ids else "Agent"
|
335
|
+
else:
|
336
|
+
if id not in self._agent_ids and id not in self._org_ids:
|
337
|
+
raise ValueError(f"Invalid id {id}, this id does not exist!")
|
338
|
+
request_type = "Org" if id in self._org_ids else "Agent"
|
239
339
|
if request_type == "Org":
|
240
340
|
original_value = await self.get_org(id)
|
241
341
|
else:
|
242
342
|
original_value = await self.get_agent(id)
|
243
343
|
if mode == "merge":
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
if _orig_type != _new_type:
|
248
|
-
logger.debug(
|
249
|
-
f"Inconsistent type of original value {_orig_type.__name__} and to-update value {_new_type.__name__}"
|
250
|
-
)
|
344
|
+
if isinstance(original_value, list):
|
345
|
+
for i in range(len(original_value)):
|
346
|
+
self._merge(original_value[i], key, value[i])
|
251
347
|
else:
|
252
|
-
|
253
|
-
orig_value.update(set(value))
|
254
|
-
original_value[key] = orig_value
|
255
|
-
elif isinstance(orig_value, dict):
|
256
|
-
orig_value.update(dict(value))
|
257
|
-
original_value[key] = orig_value
|
258
|
-
elif isinstance(orig_value, list):
|
259
|
-
orig_value.extend(list(value))
|
260
|
-
original_value[key] = orig_value
|
261
|
-
else:
|
262
|
-
logger.warning(
|
263
|
-
f"Type of {type(orig_value)} does not support mode `merge`, using `replace` instead!"
|
264
|
-
)
|
348
|
+
self._merge(original_value, key, value)
|
265
349
|
else:
|
266
|
-
original_value
|
350
|
+
if isinstance(original_value, list):
|
351
|
+
for i in range(len(original_value)):
|
352
|
+
original_value[i][key] = value[i]
|
353
|
+
else:
|
354
|
+
original_value[key] = value
|
267
355
|
if request_type == "Org":
|
268
|
-
|
269
|
-
|
270
|
-
|
356
|
+
if isinstance(original_value, list):
|
357
|
+
# batch_update_tasks = []
|
358
|
+
# for org in original_value:
|
359
|
+
# batch_update_tasks.append(self._aio_stub.UpdateOrg(
|
360
|
+
# org_service.UpdateOrgRequest(
|
361
|
+
# org=org
|
362
|
+
# )
|
363
|
+
# ))
|
364
|
+
# await asyncio.gather(*batch_update_tasks)
|
365
|
+
await self._aio_stub.BatchUpdate(
|
366
|
+
org_service.BatchUpdateRequest(
|
367
|
+
orgs=original_value,
|
368
|
+
agents=None
|
369
|
+
)
|
370
|
+
)
|
371
|
+
else:
|
372
|
+
await self._aio_stub.UpdateOrg(
|
373
|
+
org_service.UpdateOrgRequest(
|
374
|
+
org=original_value
|
375
|
+
)
|
376
|
+
)
|
271
377
|
log["consumption"] = time.time() - start_time
|
272
378
|
self._log_list.append(log)
|
273
379
|
else:
|
274
|
-
|
275
|
-
|
276
|
-
|
380
|
+
if isinstance(original_value, list):
|
381
|
+
# batch_update_tasks = []
|
382
|
+
# for agent in original_value:
|
383
|
+
# batch_update_tasks.append(self._aio_stub.UpdateAgent(
|
384
|
+
# org_service.UpdateAgentRequest(
|
385
|
+
# agent=agent
|
386
|
+
# )
|
387
|
+
# ))
|
388
|
+
# await asyncio.gather(*batch_update_tasks)
|
389
|
+
await self._aio_stub.BatchUpdate(
|
390
|
+
org_service.BatchUpdateRequest(
|
391
|
+
orgs=None,
|
392
|
+
agents=original_value
|
393
|
+
)
|
394
|
+
)
|
395
|
+
else:
|
396
|
+
await self._aio_stub.UpdateAgent(
|
397
|
+
org_service.UpdateAgentRequest(
|
398
|
+
agent=original_value
|
399
|
+
)
|
400
|
+
)
|
277
401
|
log["consumption"] = time.time() - start_time
|
278
402
|
self._log_list.append(log)
|
279
403
|
|
@@ -367,6 +491,8 @@ class EconomyClient:
|
|
367
491
|
working_hours=config.get("working_hours", []),
|
368
492
|
employees=config.get("employees", []),
|
369
493
|
citizens=config.get("citizens", []),
|
494
|
+
demand=config.get("demand", 0),
|
495
|
+
sales=config.get("sales", 0),
|
370
496
|
)
|
371
497
|
)
|
372
498
|
)
|
@@ -444,6 +570,23 @@ class EconomyClient:
|
|
444
570
|
log["consumption"] = time.time() - start_time
|
445
571
|
self._log_list.append(log)
|
446
572
|
return response.actual_consumption
|
573
|
+
|
574
|
+
async def calculate_real_gdp(self, nbs_id: int):
|
575
|
+
start_time = time.time()
|
576
|
+
log = {
|
577
|
+
"req": "calculate_real_gdp",
|
578
|
+
"start_time": start_time,
|
579
|
+
"consumption": 0
|
580
|
+
}
|
581
|
+
request = org_service.CalculateRealGDPRequest(
|
582
|
+
nbs_agent_id=nbs_id
|
583
|
+
)
|
584
|
+
response: org_service.CalculateRealGDPResponse = (
|
585
|
+
await self._aio_stub.CalculateRealGDP(request)
|
586
|
+
)
|
587
|
+
log["consumption"] = time.time() - start_time
|
588
|
+
self._log_list.append(log)
|
589
|
+
return response.real_gdp
|
447
590
|
|
448
591
|
async def calculate_interest(self, org_id: int, agent_ids: list[int]):
|
449
592
|
"""
|
@@ -114,7 +114,7 @@ class Simulator:
|
|
114
114
|
map_file=_map_pb_path,
|
115
115
|
max_day=config["simulator"].get("max_day", 1000),
|
116
116
|
start_step=config["simulator"].get("start_step", 28800),
|
117
|
-
total_step=
|
117
|
+
total_step=24*60*60,
|
118
118
|
log_dir=config["simulator"].get("log_dir", "./log"),
|
119
119
|
min_step_time=config["simulator"].get("min_step_time", 1000),
|
120
120
|
sim_addr=config["simulator"].get("server", None),
|
pycityagent/llm/llm.py
CHANGED
@@ -285,6 +285,12 @@ class LLM:
|
|
285
285
|
await asyncio.sleep(2**attempt)
|
286
286
|
else:
|
287
287
|
raise e
|
288
|
+
except Exception as e:
|
289
|
+
print("An error occurred:", e)
|
290
|
+
if attempt < retries - 1:
|
291
|
+
await asyncio.sleep(2**attempt)
|
292
|
+
else:
|
293
|
+
raise e
|
288
294
|
elif self.config.text["request_type"] == "zhipuai":
|
289
295
|
for attempt in range(retries):
|
290
296
|
try:
|
@@ -335,6 +341,12 @@ class LLM:
|
|
335
341
|
await asyncio.sleep(2**attempt)
|
336
342
|
else:
|
337
343
|
raise e
|
344
|
+
except Exception as e:
|
345
|
+
print("An error occurred:", e)
|
346
|
+
if attempt < retries - 1:
|
347
|
+
await asyncio.sleep(2**attempt)
|
348
|
+
else:
|
349
|
+
raise e
|
338
350
|
else:
|
339
351
|
print("ERROR: Wrong Config")
|
340
352
|
return "wrong config"
|
pycityagent/pycityagent-sim
CHANGED
Binary file
|
@@ -1029,7 +1029,7 @@ class AgentSimulation:
|
|
1029
1029
|
await self.resume_simulator()
|
1030
1030
|
insert_tasks = []
|
1031
1031
|
for group in self._groups.values():
|
1032
|
-
insert_tasks.append(group.
|
1032
|
+
insert_tasks.append(group.insert_agent.remote())
|
1033
1033
|
await asyncio.gather(*insert_tasks)
|
1034
1034
|
|
1035
1035
|
# step
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: pycityagent
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.0a82
|
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
|
@@ -45,7 +45,7 @@ Requires-Dist: openai>=1.58.1
|
|
45
45
|
Requires-Dist: Pillow<12.0.0,>=11.0.0
|
46
46
|
Requires-Dist: protobuf<5.0.0,<=4.24.0
|
47
47
|
Requires-Dist: pycitydata>=1.0.3
|
48
|
-
Requires-Dist: pycityproto>=2.2.
|
48
|
+
Requires-Dist: pycityproto>=2.2.3
|
49
49
|
Requires-Dist: requests>=2.32.3
|
50
50
|
Requires-Dist: Shapely>=2.0.6
|
51
51
|
Requires-Dist: PyYAML>=6.0.2
|
@@ -1,15 +1,15 @@
|
|
1
|
-
pycityagent/pycityagent-sim,sha256=
|
1
|
+
pycityagent/pycityagent-sim,sha256=MmiGNhZgGjXYLJ2EYTGMhfGAZU8TnU7ORsJ6kdtzjDs,36973378
|
2
2
|
pycityagent/__init__.py,sha256=PUKWTXc-xdMG7px8oTNclodsILUgypANj2Z647sY63k,808
|
3
3
|
pycityagent/pycityagent-ui,sha256=Ur95yZygIaZ5l_CDqP9394M5GQ66iV5PkcNPYFWqzvk,41225346
|
4
4
|
pycityagent/metrics/mlflow_client.py,sha256=-iyh4BPVnBkluhmfucUzibCUnBX2iftkz4tVJJVxwHw,6958
|
5
5
|
pycityagent/metrics/__init__.py,sha256=X08PaBbGVAd7_PRGLREXWxaqm7nS82WBQpD1zvQzcqc,128
|
6
6
|
pycityagent/economy/__init__.py,sha256=aonY4WHnx-6EGJ4WKrx4S-2jAkYNLtqUA04jp6q8B7w,75
|
7
|
-
pycityagent/economy/econ_client.py,sha256=
|
7
|
+
pycityagent/economy/econ_client.py,sha256=jDF_KAqFwM-vrFNRHiinYJEPEbzfaU2gRp_hIMk27O4,29208
|
8
8
|
pycityagent/tools/__init__.py,sha256=y7sMVMHf0AbivlczM2h-kr7mkgXK-WAx3S9BXLXkWvw,235
|
9
9
|
pycityagent/tools/tool.py,sha256=4ZJSHbNM8dfAVwZEw8T0a2_9OuPsPQpKSVL4WxZVBUc,9022
|
10
10
|
pycityagent/llm/llmconfig.py,sha256=6AqCMV4B_JqBD2mb98bLGzpUdlOCnziQKae-Hhxxp-E,469
|
11
11
|
pycityagent/llm/__init__.py,sha256=iWs6FLgrbRVIiqOf4ILS89gkVCTvS7HFC3vG-MWuyko,205
|
12
|
-
pycityagent/llm/llm.py,sha256=
|
12
|
+
pycityagent/llm/llm.py,sha256=A1Q-dKEXHJKhBnElI7Ci6eIK-A7I-UZNQxC_hEgEa-4,20018
|
13
13
|
pycityagent/llm/embeddings.py,sha256=3610I-_scAy8HwRNpT8hVJpH9_8_pTLCPptqnzSq10o,11322
|
14
14
|
pycityagent/llm/utils.py,sha256=rSx_fp-_Gh0vZ-x2rqAUqnpS56BVTZ4ChfAMarB8S1A,195
|
15
15
|
pycityagent/memory/memory.py,sha256=5mUweo-BgQYbXmVRAk7HTUXsar6O6iYz79VbLuMAvjo,45063
|
@@ -21,7 +21,7 @@ pycityagent/memory/utils.py,sha256=oJWLdPeJy_jcdKcDTo9JAH9kDZhqjoQhhv_zT9qWC0w,8
|
|
21
21
|
pycityagent/memory/const.py,sha256=nFmjvt-8FEB0hc0glOH3lliqJhkhf3D_NKxWI0pf6TY,936
|
22
22
|
pycityagent/memory/faiss_query.py,sha256=KPeyzIjD0dzkxr-TlOeCiIlkdh1WAyyipCAXUEt97Lk,17350
|
23
23
|
pycityagent/memory/state.py,sha256=JFCBuK1AS-HqscvdGS9ATF9AUU8t29_2leDY_6iO2_4,5158
|
24
|
-
pycityagent/simulation/simulation.py,sha256=
|
24
|
+
pycityagent/simulation/simulation.py,sha256=_dmTQDVaKHpmAljKxQBFkVk9FDSBJg_PA5PMyphQ5D4,49525
|
25
25
|
pycityagent/simulation/__init__.py,sha256=u1WpgwVxPboXWMxrUQKMXJNmTKQYAeCaqZv9HmSxESY,118
|
26
26
|
pycityagent/simulation/agentgroup.py,sha256=oXo2iRUThh_96JhXHMufT8_BPx0PrlwqbMpiVqK_viA,36957
|
27
27
|
pycityagent/simulation/storage/pg.py,sha256=xRshSOGttW-p0re0fNBOjOpb-nQ5msIE2LsdT79_E_Y,8425
|
@@ -39,14 +39,14 @@ pycityagent/utils/parsers/parser_base.py,sha256=ZbqRcqOBL9hfHVZSltQSQmJnWrtuJS9a
|
|
39
39
|
pycityagent/utils/parsers/json_parser.py,sha256=sakKohUuMcUH2toR85CAG_37D02ZoAn6LlzLgftUjmo,2923
|
40
40
|
pycityagent/agent/agent_base.py,sha256=nz9QNfNjWVDza1yd8OwqmjZM3sq4fqONnVpcI8mA8cI,39488
|
41
41
|
pycityagent/agent/__init__.py,sha256=U20yKu9QwSqAx_PHk5JwipfODkDfxONtumVfnsKjWFg,180
|
42
|
-
pycityagent/agent/agent.py,sha256=
|
42
|
+
pycityagent/agent/agent.py,sha256=Ymv3CtEPGcayVWrNnXkeWQXRNYEuvniWCqUfn2UZy8Y,19073
|
43
43
|
pycityagent/cli/wrapper.py,sha256=bAwmfWTXbGld-uiMnIMhKp22IVRQjhLUToknyUDk9rQ,1147
|
44
44
|
pycityagent/workflow/__init__.py,sha256=H08Ko3eliZvuuCMajbEri-IP4-SeswYU6UjHBNA4Ze0,490
|
45
45
|
pycityagent/workflow/prompt.py,sha256=rzenP4EFGxbWE1aq-x2036b6umKvi5cQx2xtWULwgIk,3392
|
46
46
|
pycityagent/workflow/block.py,sha256=WJfCeL8e117GzkVPJCRNsQZZinccMnVyEubkwrf-17U,12295
|
47
47
|
pycityagent/workflow/trigger.py,sha256=4nzAwywGQsFabgo6gzp-vD2EV4wII7Z0LHGEAsflSEY,7608
|
48
48
|
pycityagent/environment/__init__.py,sha256=fFIth2jxxgZ92cXm-aoM2igHgaSqsYGwtBhyb7opjzk,166
|
49
|
-
pycityagent/environment/simulator.py,sha256=
|
49
|
+
pycityagent/environment/simulator.py,sha256=I5xDg-1Cn32qvKN7X_6SklA_d_iPFS9THsZqbZreJDU,22606
|
50
50
|
pycityagent/environment/utils/port.py,sha256=3OM6kSUt3PxvDUOlgyiendBtETaWU8Mzk_8H0TzTmYg,295
|
51
51
|
pycityagent/environment/utils/grpc.py,sha256=_lB4-k4dTKuNvApaDiYgFxiLTPtYG42DVQtG9yOj9pQ,2022
|
52
52
|
pycityagent/environment/utils/base64.py,sha256=hoREzQo3FXMN79pqQLO2jgsDEvudciomyKii7MWljAM,374
|
@@ -58,7 +58,7 @@ pycityagent/environment/utils/const.py,sha256=1LqxnYJ8FSmq37fN5kIFlWLwycEDzFa8SF
|
|
58
58
|
pycityagent/environment/sim/pause_service.py,sha256=UUTa4pTBOX_MGKki9QDgKId7scch0waAWF9xRVmNlAs,1701
|
59
59
|
pycityagent/environment/sim/person_service.py,sha256=T1pRi5jDcivSInX7iGZoHKYZmgO7_t5MYtLhU12_LC4,10793
|
60
60
|
pycityagent/environment/sim/aoi_service.py,sha256=bYVJDrOfDn8hgOORDU7PxMaT-fpqXA5Z0A080l2EPBc,1242
|
61
|
-
pycityagent/environment/sim/sim_env.py,sha256=
|
61
|
+
pycityagent/environment/sim/sim_env.py,sha256=4CW9lv9CyRUFsa0mwZ3AQsBps3i1Qh1KIRSgHdZWy0U,4658
|
62
62
|
pycityagent/environment/sim/lane_service.py,sha256=bmf0zOWkxDzMEDlhTdHNRJRiTFGgzjbeqmex387gHZs,3964
|
63
63
|
pycityagent/environment/sim/client.py,sha256=x4REWPRFG_C2s0-CWz8MnYalD_esfu2pPHf_vpsCG78,2852
|
64
64
|
pycityagent/environment/sim/__init__.py,sha256=CyJc5Tey9MgzomZv0ynAcV0yaUlSE3bPbegYXar8wJc,601
|
@@ -67,18 +67,18 @@ pycityagent/environment/sim/light_service.py,sha256=q4pKcGrm7WU0h29I1dFIDOz2OV0B
|
|
67
67
|
pycityagent/environment/sim/clock_service.py,sha256=4Hly8CToghj0x_XbDgGrIZy1YYAlDH0EUGCiCDYpk_I,1375
|
68
68
|
pycityagent/environment/sim/road_service.py,sha256=Bb1sreO0Knt9tcqH_WJF-I3P3G92bRAlzDBEa--25GE,1297
|
69
69
|
pycityagent/cityagent/metrics.py,sha256=yXZ4uRXARjDAvPKyquut7YWs363nDcIV0J1KQgYacZE,2169
|
70
|
-
pycityagent/cityagent/memory_config.py,sha256=
|
71
|
-
pycityagent/cityagent/bankagent.py,sha256=
|
70
|
+
pycityagent/cityagent/memory_config.py,sha256=T21XdQ-um16LMMirLO2W14LcbJp3afnYF-AsUZKfxWM,11923
|
71
|
+
pycityagent/cityagent/bankagent.py,sha256=I6MNG1fUbxKyWCLxCtvOjeVahong_LhHQKmJdRPhQL8,4097
|
72
72
|
pycityagent/cityagent/__init__.py,sha256=gcBQ-a50XegFtjigQ7xDXRBZrywBKqifiQFSRnEF8gM,572
|
73
|
-
pycityagent/cityagent/firmagent.py,sha256=
|
74
|
-
pycityagent/cityagent/nbsagent.py,sha256=
|
75
|
-
pycityagent/cityagent/initial.py,sha256=
|
73
|
+
pycityagent/cityagent/firmagent.py,sha256=vZr7kdjnxcCZ5qX7hmUIYuQQWd44GcRPbdi76WGSFy4,3760
|
74
|
+
pycityagent/cityagent/nbsagent.py,sha256=knSaQbCNkWi7bZjwwEr_hTKj44_q67eHif6HI3W9i1M,4558
|
75
|
+
pycityagent/cityagent/initial.py,sha256=0DSOWnVVknMw6xoJWfdZUFBH3yti8y800wnkXXCocxY,6194
|
76
76
|
pycityagent/cityagent/societyagent.py,sha256=dY8coUMtrTrcATCYDdI0MvVt42YXSyP-ZWi24H9xg7o,20090
|
77
77
|
pycityagent/cityagent/message_intercept.py,sha256=dyT1G-nMxKb2prhgtyFFHFz593qBrkk5DnHsHvG1OIc,4418
|
78
78
|
pycityagent/cityagent/governmentagent.py,sha256=XIyggG83FWUTZdOuoqc6ClCP3hhfkxNmtYRu9TFo0dU,3063
|
79
79
|
pycityagent/cityagent/blocks/dispatcher.py,sha256=U5BPeUrjrTyDaznYfT6YUJIW8vfKVRDF4EO0oOn6Td4,2886
|
80
80
|
pycityagent/cityagent/blocks/needs_block.py,sha256=NYKrGDoYCuXoupMNMuSNhx4Ci1paC_EuGRWvp5-ZSA8,15909
|
81
|
-
pycityagent/cityagent/blocks/cognition_block.py,sha256=
|
81
|
+
pycityagent/cityagent/blocks/cognition_block.py,sha256=yzjB0D_95vytpa5xiVdmTSpGp8H9HXcjWzzFN0OpP0k,15398
|
82
82
|
pycityagent/cityagent/blocks/social_block.py,sha256=eedOlwRTGI47QFELYmfe2a_aj0GuHJweSyDxA6AYXcU,15493
|
83
83
|
pycityagent/cityagent/blocks/__init__.py,sha256=h6si6WBcVVuglIskKQKA8Cxtf_VKen1sNPqOFKI311Q,420
|
84
84
|
pycityagent/cityagent/blocks/economy_block.py,sha256=1yHUdCSAzvvhdGFzMfSM_wtbW_3D6YeYSNlVV3yQqsA,19083
|
@@ -89,9 +89,9 @@ pycityagent/cityagent/blocks/mobility_block.py,sha256=qkRiV0nkGOUUoo9lGIjAFE_Hl0
|
|
89
89
|
pycityagent/survey/models.py,sha256=g3xni4GcA1Py3vlGt6z4ltutjgQ4G0uINYAM8vKRJAw,5225
|
90
90
|
pycityagent/survey/__init__.py,sha256=rxwou8U9KeFSP7rMzXtmtp2fVFZxK4Trzi-psx9LPIs,153
|
91
91
|
pycityagent/survey/manager.py,sha256=tHkdeq4lTfAHwvgf4-udsXri0z2l6E00rEbvwl7SqRs,3439
|
92
|
-
pycityagent-2.0.
|
93
|
-
pycityagent-2.0.
|
94
|
-
pycityagent-2.0.
|
95
|
-
pycityagent-2.0.
|
96
|
-
pycityagent-2.0.
|
97
|
-
pycityagent-2.0.
|
92
|
+
pycityagent-2.0.0a82.dist-info/RECORD,,
|
93
|
+
pycityagent-2.0.0a82.dist-info/LICENSE,sha256=n2HPXiupinpyHMnIkbCf3OTYd3KMqbmldu1e7av0CAU,1084
|
94
|
+
pycityagent-2.0.0a82.dist-info/WHEEL,sha256=NW1RskY9zow1Y68W-gXg0oZyBRAugI1JHywIzAIai5o,109
|
95
|
+
pycityagent-2.0.0a82.dist-info/entry_points.txt,sha256=BZcne49AAIFv-hawxGnPbblea7X3MtAtoPyDX8L4OC4,132
|
96
|
+
pycityagent-2.0.0a82.dist-info/top_level.txt,sha256=yOmeu6cSXmiUtScu53a3s0p7BGtLMaV0aff83EHCTic,43
|
97
|
+
pycityagent-2.0.0a82.dist-info/METADATA,sha256=a48d_5hO9dLaPc6fmDJ4N-T83VWIwdmEJQFGMk1rlxw,9110
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|