pycityagent 2.0.0a66__cp312-cp312-macosx_11_0_arm64.whl → 2.0.0a67__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/agent/agent.py +157 -57
- pycityagent/agent/agent_base.py +316 -43
- pycityagent/cityagent/bankagent.py +49 -9
- pycityagent/cityagent/blocks/__init__.py +1 -2
- pycityagent/cityagent/blocks/cognition_block.py +54 -31
- pycityagent/cityagent/blocks/dispatcher.py +22 -17
- pycityagent/cityagent/blocks/economy_block.py +46 -32
- pycityagent/cityagent/blocks/mobility_block.py +130 -100
- pycityagent/cityagent/blocks/needs_block.py +101 -44
- pycityagent/cityagent/blocks/other_block.py +42 -33
- pycityagent/cityagent/blocks/plan_block.py +59 -42
- pycityagent/cityagent/blocks/social_block.py +167 -116
- pycityagent/cityagent/blocks/utils.py +13 -6
- pycityagent/cityagent/firmagent.py +17 -35
- pycityagent/cityagent/governmentagent.py +3 -3
- pycityagent/cityagent/initial.py +79 -44
- pycityagent/cityagent/memory_config.py +108 -88
- pycityagent/cityagent/message_intercept.py +0 -4
- pycityagent/cityagent/metrics.py +41 -0
- pycityagent/cityagent/nbsagent.py +24 -36
- pycityagent/cityagent/societyagent.py +7 -3
- pycityagent/cli/wrapper.py +2 -2
- pycityagent/economy/econ_client.py +407 -81
- pycityagent/environment/__init__.py +0 -3
- pycityagent/environment/sim/__init__.py +0 -3
- pycityagent/environment/sim/aoi_service.py +2 -2
- pycityagent/environment/sim/client.py +3 -31
- pycityagent/environment/sim/clock_service.py +2 -2
- pycityagent/environment/sim/lane_service.py +8 -8
- pycityagent/environment/sim/light_service.py +8 -8
- pycityagent/environment/sim/pause_service.py +9 -10
- pycityagent/environment/sim/person_service.py +20 -20
- pycityagent/environment/sim/road_service.py +2 -2
- pycityagent/environment/sim/sim_env.py +21 -5
- pycityagent/environment/sim/social_service.py +4 -4
- pycityagent/environment/simulator.py +249 -27
- pycityagent/environment/utils/__init__.py +2 -2
- pycityagent/environment/utils/geojson.py +2 -2
- pycityagent/environment/utils/grpc.py +4 -4
- pycityagent/environment/utils/map_utils.py +2 -2
- pycityagent/llm/embeddings.py +147 -28
- pycityagent/llm/llm.py +122 -77
- pycityagent/llm/llmconfig.py +5 -0
- pycityagent/llm/utils.py +4 -0
- pycityagent/memory/__init__.py +0 -4
- pycityagent/memory/const.py +2 -2
- pycityagent/memory/faiss_query.py +140 -61
- pycityagent/memory/memory.py +393 -90
- pycityagent/memory/memory_base.py +140 -34
- pycityagent/memory/profile.py +13 -13
- pycityagent/memory/self_define.py +13 -13
- pycityagent/memory/state.py +14 -14
- pycityagent/message/message_interceptor.py +253 -3
- pycityagent/message/messager.py +133 -6
- pycityagent/metrics/mlflow_client.py +47 -4
- pycityagent/pycityagent-sim +0 -0
- pycityagent/pycityagent-ui +0 -0
- pycityagent/simulation/__init__.py +3 -2
- pycityagent/simulation/agentgroup.py +145 -52
- pycityagent/simulation/simulation.py +257 -62
- pycityagent/survey/manager.py +45 -3
- pycityagent/survey/models.py +42 -2
- pycityagent/tools/__init__.py +1 -2
- pycityagent/tools/tool.py +93 -69
- pycityagent/utils/avro_schema.py +2 -2
- pycityagent/utils/parsers/code_block_parser.py +1 -1
- pycityagent/utils/parsers/json_parser.py +2 -2
- pycityagent/utils/parsers/parser_base.py +2 -2
- pycityagent/workflow/block.py +64 -13
- pycityagent/workflow/prompt.py +31 -23
- pycityagent/workflow/trigger.py +91 -24
- {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/METADATA +2 -2
- pycityagent-2.0.0a67.dist-info/RECORD +97 -0
- pycityagent/environment/interact/__init__.py +0 -0
- pycityagent/environment/interact/interact.py +0 -198
- pycityagent/environment/message/__init__.py +0 -0
- pycityagent/environment/sence/__init__.py +0 -0
- pycityagent/environment/sence/static.py +0 -416
- pycityagent/environment/sidecar/__init__.py +0 -8
- pycityagent/environment/sidecar/sidecarv2.py +0 -109
- pycityagent/environment/sim/economy_services.py +0 -192
- pycityagent/metrics/utils/const.py +0 -0
- pycityagent-2.0.0a66.dist-info/RECORD +0 -105
- {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/LICENSE +0 -0
- {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/WHEEL +0 -0
- {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/entry_points.txt +0 -0
- {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/top_level.txt +0 -0
pycityagent/agent/agent.py
CHANGED
@@ -19,10 +19,23 @@ from .agent_base import Agent, AgentType
|
|
19
19
|
|
20
20
|
logger = logging.getLogger("pycityagent")
|
21
21
|
|
22
|
+
__all__ = [
|
23
|
+
"InstitutionAgent",
|
24
|
+
"CitizenAgent",
|
25
|
+
]
|
26
|
+
|
22
27
|
|
23
28
|
class CitizenAgent(Agent):
|
24
29
|
"""
|
25
|
-
|
30
|
+
Represents a citizen agent within the simulation environment.
|
31
|
+
|
32
|
+
- **Description**:
|
33
|
+
- This class extends the base `Agent` class and is designed to simulate the behavior of a city resident.
|
34
|
+
- It includes initialization of various clients (like LLM, economy) and services required for the agent's operation.
|
35
|
+
- Provides methods for binding the agent to the simulator and economy system, as well as handling specific types of messages.
|
36
|
+
|
37
|
+
- **Attributes**:
|
38
|
+
- `_mlflow_client`: An optional client for integrating with MLflow for experiment tracking and management.
|
26
39
|
"""
|
27
40
|
|
28
41
|
def __init__(
|
@@ -36,6 +49,22 @@ class CitizenAgent(Agent):
|
|
36
49
|
message_interceptor: Optional[MessageInterceptor] = None, # type:ignore
|
37
50
|
avro_file: Optional[dict] = None,
|
38
51
|
) -> None:
|
52
|
+
"""
|
53
|
+
Initialize a new instance of the CitizenAgent.
|
54
|
+
|
55
|
+
- **Args**:
|
56
|
+
- `name` (`str`): The name or identifier of the agent.
|
57
|
+
- `llm_client` (`Optional[LLM]`, optional): A client for interacting with a Language Model. Defaults to `None`.
|
58
|
+
- `simulator` (`Optional[Simulator]`, optional): A reference to the simulation environment. Defaults to `None`.
|
59
|
+
- `memory` (`Optional[Memory]`, optional): A memory storage object for the agent. Defaults to `None`.
|
60
|
+
- `economy_client` (`Optional[EconomyClient]`, optional): A client for managing economic transactions. Defaults to `None`.
|
61
|
+
- `messager` (`Optional[Messager]`, optional): A communication service for messaging between agents. Defaults to `None`.
|
62
|
+
- `message_interceptor` (`Optional[MessageInterceptor]`, optional): An interceptor for modifying messages before they are processed. Defaults to `None`.
|
63
|
+
- `avro_file` (`Optional[dict]`, optional): Configuration for writing data in Avro format. Defaults to `None`.
|
64
|
+
|
65
|
+
- **Description**:
|
66
|
+
- Initializes the CitizenAgent with the provided parameters and sets up necessary internal states.
|
67
|
+
"""
|
39
68
|
super().__init__(
|
40
69
|
name=name,
|
41
70
|
type=AgentType.Citizen,
|
@@ -50,15 +79,24 @@ class CitizenAgent(Agent):
|
|
50
79
|
self._mlflow_client = None
|
51
80
|
|
52
81
|
async def bind_to_simulator(self):
|
82
|
+
"""
|
83
|
+
Bind the agent to both the Traffic Simulator and Economy Simulator.
|
84
|
+
|
85
|
+
- **Description**:
|
86
|
+
- Calls the `_bind_to_simulator` method to establish the agent within the simulation environment.
|
87
|
+
- Calls the `_bind_to_economy` method to integrate the agent into the economy simulator.
|
88
|
+
"""
|
53
89
|
await self._bind_to_simulator()
|
54
90
|
await self._bind_to_economy()
|
55
91
|
|
56
92
|
async def _bind_to_simulator(self):
|
57
93
|
"""
|
58
|
-
Bind
|
94
|
+
Bind the agent to the Traffic Simulator.
|
59
95
|
|
60
|
-
|
61
|
-
|
96
|
+
- **Description**:
|
97
|
+
- If the simulator is set, this method binds the agent by creating a person entity in the simulator based on the agent's attributes.
|
98
|
+
- Updates the agent's status with the newly created person ID from the simulator.
|
99
|
+
- Logs the successful binding to the person entity added to the simulator.
|
62
100
|
"""
|
63
101
|
if self._simulator is None:
|
64
102
|
logger.warning("Simulator is not set")
|
@@ -90,6 +128,13 @@ class CitizenAgent(Agent):
|
|
90
128
|
self.status.set_agent_id(person_id)
|
91
129
|
|
92
130
|
async def _bind_to_economy(self):
|
131
|
+
"""
|
132
|
+
Bind the agent to the Economy Simulator.
|
133
|
+
|
134
|
+
- **Description**:
|
135
|
+
- If the economy client is set and the agent has not yet been bound to the economy, this method removes any existing agent with the same ID and adds the current agent to the economy.
|
136
|
+
- Sets `_has_bound_to_economy` to `True` after successfully adding the agent.
|
137
|
+
"""
|
93
138
|
if self._economy_client is None:
|
94
139
|
logger.warning("Economy client is not set")
|
95
140
|
return
|
@@ -100,16 +145,33 @@ class CitizenAgent(Agent):
|
|
100
145
|
pass
|
101
146
|
person_id = await self.status.get("id")
|
102
147
|
currency = await self.status.get("currency")
|
148
|
+
skill = await self.status.get("work_skill")
|
149
|
+
consumption = await self.status.get("consumption")
|
150
|
+
income = await self.status.get("income")
|
103
151
|
await self._economy_client.add_agents(
|
104
152
|
{
|
105
153
|
"id": person_id,
|
106
154
|
"currency": currency,
|
155
|
+
"skill": skill,
|
156
|
+
"consumption": consumption,
|
157
|
+
"income": income,
|
107
158
|
}
|
108
159
|
)
|
109
160
|
self._has_bound_to_economy = True
|
110
161
|
|
111
162
|
async def handle_gather_message(self, payload: dict):
|
112
|
-
"""
|
163
|
+
"""
|
164
|
+
Handle a gather message received by the agent.
|
165
|
+
|
166
|
+
- **Args**:
|
167
|
+
- `payload` (`dict`): The message payload containing the target attribute and sender ID.
|
168
|
+
|
169
|
+
- **Description**:
|
170
|
+
- Extracts the target attribute and sender ID from the payload.
|
171
|
+
- Retrieves the content associated with the target attribute from the agent's status.
|
172
|
+
- Prepares a response payload with the retrieved content and sends it back to the sender using `_send_message`.
|
173
|
+
"""
|
174
|
+
# 处理收到的消息,识别发送者
|
113
175
|
# 从消息中解析发送者 ID 和消息内容
|
114
176
|
target = payload["target"]
|
115
177
|
sender_id = payload["from"]
|
@@ -138,7 +200,16 @@ class CitizenAgent(Agent):
|
|
138
200
|
|
139
201
|
class InstitutionAgent(Agent):
|
140
202
|
"""
|
141
|
-
|
203
|
+
Represents an institution agent within the simulation environment.
|
204
|
+
|
205
|
+
- **Description**:
|
206
|
+
- This class extends the base `Agent` class and is designed to simulate the behavior of an institution, such as a bank, government body, or corporation.
|
207
|
+
- It includes initialization of various clients (like LLM, economy) and services required for the agent's operation.
|
208
|
+
- Provides methods for binding the agent to the economy system and handling specific types of messages, like gathering information from other agents.
|
209
|
+
|
210
|
+
- **Attributes**:
|
211
|
+
- `_mlflow_client`: An optional client for integrating with MLflow for experiment tracking and management.
|
212
|
+
- `_gather_responses`: A dictionary mapping agent UUIDs to `asyncio.Future` objects used for collecting responses to gather requests.
|
142
213
|
"""
|
143
214
|
|
144
215
|
def __init__(
|
@@ -152,6 +223,23 @@ class InstitutionAgent(Agent):
|
|
152
223
|
message_interceptor: Optional[MessageInterceptor] = None, # type:ignore
|
153
224
|
avro_file: Optional[dict] = None,
|
154
225
|
) -> None:
|
226
|
+
"""
|
227
|
+
Initialize a new instance of the InstitutionAgent.
|
228
|
+
|
229
|
+
- **Args**:
|
230
|
+
- `name` (`str`): The name or identifier of the agent.
|
231
|
+
- `llm_client` (`Optional[LLM]`, optional): A client for interacting with a Language Model. Defaults to `None`.
|
232
|
+
- `simulator` (`Optional[Simulator]`, optional): A reference to the simulation environment. Defaults to `None`.
|
233
|
+
- `memory` (`Optional[Memory]`, optional): A memory storage object for the agent. Defaults to `None`.
|
234
|
+
- `economy_client` (`Optional[EconomyClient]`, optional): A client for managing economic transactions. Defaults to `None`.
|
235
|
+
- `messager` (`Optional[Messager]`, optional): A communication service for messaging between agents. Defaults to `None`.
|
236
|
+
- `message_interceptor` (`Optional[MessageInterceptor]`, optional): An interceptor for modifying messages before they are processed. Defaults to `None`.
|
237
|
+
- `avro_file` (`Optional[dict]`, optional): Configuration for writing data in Avro format. Defaults to `None`.
|
238
|
+
|
239
|
+
- **Description**:
|
240
|
+
- Initializes the InstitutionAgent with the provided parameters and sets up necessary internal states.
|
241
|
+
- Adds a response collector (`_gather_responses`) for handling responses to gather requests.
|
242
|
+
"""
|
155
243
|
super().__init__(
|
156
244
|
name=name,
|
157
245
|
type=AgentType.Institution,
|
@@ -168,9 +256,22 @@ class InstitutionAgent(Agent):
|
|
168
256
|
self._gather_responses: dict[str, asyncio.Future] = {}
|
169
257
|
|
170
258
|
async def bind_to_simulator(self):
|
259
|
+
"""
|
260
|
+
Bind the agent to the Economy Simulator.
|
261
|
+
|
262
|
+
- **Description**:
|
263
|
+
- Calls the `_bind_to_economy` method to integrate the agent into the economy simulator.
|
264
|
+
"""
|
171
265
|
await self._bind_to_economy()
|
172
266
|
|
173
267
|
async def _bind_to_economy(self):
|
268
|
+
"""
|
269
|
+
Bind the agent to the Economy Simulator.
|
270
|
+
|
271
|
+
- **Description**:
|
272
|
+
- Calls the `_bind_to_economy` method to integrate the agent into the economy system.
|
273
|
+
- Note that this method does not bind the agent to the simulator itself; it only handles the economy integration.
|
274
|
+
"""
|
174
275
|
if self._economy_client is None:
|
175
276
|
logger.debug("Economy client is not set")
|
176
277
|
return
|
@@ -210,50 +311,25 @@ class InstitutionAgent(Agent):
|
|
210
311
|
_status = self.status
|
211
312
|
_id = await _status.get("id")
|
212
313
|
_type = await _status.get("type")
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
prices = []
|
233
|
-
try:
|
234
|
-
inventory = await _status.get("inventory")
|
235
|
-
except:
|
236
|
-
inventory = 0
|
237
|
-
try:
|
238
|
-
price = await _status.get("price")
|
239
|
-
except:
|
240
|
-
price = 0
|
241
|
-
try:
|
242
|
-
currency = await _status.get("currency")
|
243
|
-
except:
|
244
|
-
currency = 0.0
|
245
|
-
try:
|
246
|
-
interest_rate = await _status.get("interest_rate")
|
247
|
-
except:
|
248
|
-
interest_rate = 0.0
|
249
|
-
try:
|
250
|
-
bracket_cutoffs = await _status.get("bracket_cutoffs")
|
251
|
-
except:
|
252
|
-
bracket_cutoffs = []
|
253
|
-
try:
|
254
|
-
bracket_rates = await _status.get("bracket_rates")
|
255
|
-
except:
|
256
|
-
bracket_rates = []
|
314
|
+
nominal_gdp = await _status.get("nominal_gdp", [])
|
315
|
+
real_gdp = await _status.get("real_gdp", [])
|
316
|
+
unemployment = await _status.get("unemployment", [])
|
317
|
+
wages = await _status.get("wages", [])
|
318
|
+
prices = await _status.get("prices", [])
|
319
|
+
inventory = await _status.get("inventory", 0)
|
320
|
+
price = await _status.get("price", 0)
|
321
|
+
currency = await _status.get("currency", 0.0)
|
322
|
+
interest_rate = await _status.get("interest_rate", 0.0)
|
323
|
+
bracket_cutoffs = await _status.get("bracket_cutoffs", [])
|
324
|
+
bracket_rates = await _status.get("bracket_rates", [])
|
325
|
+
consumption_currency = await _status.get("consumption_currency", [])
|
326
|
+
consumption_propensity = await _status.get("consumption_propensity", [])
|
327
|
+
income_currency = await _status.get("income_currency", [])
|
328
|
+
depression = await _status.get("depression", [])
|
329
|
+
locus_control = await _status.get("locus_control", [])
|
330
|
+
working_hours = await _status.get("working_hours", [])
|
331
|
+
employees = await _status.get("employees", [])
|
332
|
+
citizens = await _status.get("citizens", [])
|
257
333
|
await self._economy_client.add_orgs(
|
258
334
|
{
|
259
335
|
"id": _id,
|
@@ -269,6 +345,14 @@ class InstitutionAgent(Agent):
|
|
269
345
|
"interest_rate": interest_rate,
|
270
346
|
"bracket_cutoffs": bracket_cutoffs,
|
271
347
|
"bracket_rates": bracket_rates,
|
348
|
+
"consumption_currency": consumption_currency,
|
349
|
+
"consumption_propensity": consumption_propensity,
|
350
|
+
"income_currency": income_currency,
|
351
|
+
"depression": depression,
|
352
|
+
"locus_control": locus_control,
|
353
|
+
"working_hours": working_hours,
|
354
|
+
"employees": employees,
|
355
|
+
"citizens": citizens,
|
272
356
|
}
|
273
357
|
)
|
274
358
|
except Exception as e:
|
@@ -276,7 +360,16 @@ class InstitutionAgent(Agent):
|
|
276
360
|
self._has_bound_to_economy = True
|
277
361
|
|
278
362
|
async def handle_gather_message(self, payload: dict):
|
279
|
-
"""
|
363
|
+
"""
|
364
|
+
Handle a gather message received by the agent.
|
365
|
+
|
366
|
+
- **Args**:
|
367
|
+
- `payload` (`dict`): The message payload containing the content and sender ID.
|
368
|
+
|
369
|
+
- **Description**:
|
370
|
+
- Extracts the content and sender ID from the payload.
|
371
|
+
- Stores the response in the corresponding Future object using the sender ID as the key.
|
372
|
+
"""
|
280
373
|
content = payload["content"]
|
281
374
|
sender_id = payload["from"]
|
282
375
|
|
@@ -291,14 +384,21 @@ class InstitutionAgent(Agent):
|
|
291
384
|
)
|
292
385
|
|
293
386
|
async def gather_messages(self, agent_uuids: list[str], target: str) -> list[dict]:
|
294
|
-
"""
|
387
|
+
"""
|
388
|
+
Gather messages from multiple agents.
|
389
|
+
|
390
|
+
- **Args**:
|
391
|
+
- `agent_uuids` (`list[str]`): A list of UUIDs for the target agents.
|
392
|
+
- `target` (`str`): The type of information to collect from each agent.
|
295
393
|
|
296
|
-
|
297
|
-
|
298
|
-
target: 要收集的信息类型
|
394
|
+
- **Returns**:
|
395
|
+
- `list[dict]`: A list of dictionaries containing the collected responses.
|
299
396
|
|
300
|
-
|
301
|
-
|
397
|
+
- **Description**:
|
398
|
+
- For each agent UUID provided, creates a `Future` object to wait for its response.
|
399
|
+
- Sends a gather request to each specified agent.
|
400
|
+
- Waits for all responses and returns them as a list of dictionaries.
|
401
|
+
- Ensures cleanup of Futures after collecting responses.
|
302
402
|
"""
|
303
403
|
# 为每个agent创建Future
|
304
404
|
futures = {}
|