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.
Files changed (87) hide show
  1. pycityagent/agent/agent.py +157 -57
  2. pycityagent/agent/agent_base.py +316 -43
  3. pycityagent/cityagent/bankagent.py +49 -9
  4. pycityagent/cityagent/blocks/__init__.py +1 -2
  5. pycityagent/cityagent/blocks/cognition_block.py +54 -31
  6. pycityagent/cityagent/blocks/dispatcher.py +22 -17
  7. pycityagent/cityagent/blocks/economy_block.py +46 -32
  8. pycityagent/cityagent/blocks/mobility_block.py +130 -100
  9. pycityagent/cityagent/blocks/needs_block.py +101 -44
  10. pycityagent/cityagent/blocks/other_block.py +42 -33
  11. pycityagent/cityagent/blocks/plan_block.py +59 -42
  12. pycityagent/cityagent/blocks/social_block.py +167 -116
  13. pycityagent/cityagent/blocks/utils.py +13 -6
  14. pycityagent/cityagent/firmagent.py +17 -35
  15. pycityagent/cityagent/governmentagent.py +3 -3
  16. pycityagent/cityagent/initial.py +79 -44
  17. pycityagent/cityagent/memory_config.py +108 -88
  18. pycityagent/cityagent/message_intercept.py +0 -4
  19. pycityagent/cityagent/metrics.py +41 -0
  20. pycityagent/cityagent/nbsagent.py +24 -36
  21. pycityagent/cityagent/societyagent.py +7 -3
  22. pycityagent/cli/wrapper.py +2 -2
  23. pycityagent/economy/econ_client.py +407 -81
  24. pycityagent/environment/__init__.py +0 -3
  25. pycityagent/environment/sim/__init__.py +0 -3
  26. pycityagent/environment/sim/aoi_service.py +2 -2
  27. pycityagent/environment/sim/client.py +3 -31
  28. pycityagent/environment/sim/clock_service.py +2 -2
  29. pycityagent/environment/sim/lane_service.py +8 -8
  30. pycityagent/environment/sim/light_service.py +8 -8
  31. pycityagent/environment/sim/pause_service.py +9 -10
  32. pycityagent/environment/sim/person_service.py +20 -20
  33. pycityagent/environment/sim/road_service.py +2 -2
  34. pycityagent/environment/sim/sim_env.py +21 -5
  35. pycityagent/environment/sim/social_service.py +4 -4
  36. pycityagent/environment/simulator.py +249 -27
  37. pycityagent/environment/utils/__init__.py +2 -2
  38. pycityagent/environment/utils/geojson.py +2 -2
  39. pycityagent/environment/utils/grpc.py +4 -4
  40. pycityagent/environment/utils/map_utils.py +2 -2
  41. pycityagent/llm/embeddings.py +147 -28
  42. pycityagent/llm/llm.py +122 -77
  43. pycityagent/llm/llmconfig.py +5 -0
  44. pycityagent/llm/utils.py +4 -0
  45. pycityagent/memory/__init__.py +0 -4
  46. pycityagent/memory/const.py +2 -2
  47. pycityagent/memory/faiss_query.py +140 -61
  48. pycityagent/memory/memory.py +393 -90
  49. pycityagent/memory/memory_base.py +140 -34
  50. pycityagent/memory/profile.py +13 -13
  51. pycityagent/memory/self_define.py +13 -13
  52. pycityagent/memory/state.py +14 -14
  53. pycityagent/message/message_interceptor.py +253 -3
  54. pycityagent/message/messager.py +133 -6
  55. pycityagent/metrics/mlflow_client.py +47 -4
  56. pycityagent/pycityagent-sim +0 -0
  57. pycityagent/pycityagent-ui +0 -0
  58. pycityagent/simulation/__init__.py +3 -2
  59. pycityagent/simulation/agentgroup.py +145 -52
  60. pycityagent/simulation/simulation.py +257 -62
  61. pycityagent/survey/manager.py +45 -3
  62. pycityagent/survey/models.py +42 -2
  63. pycityagent/tools/__init__.py +1 -2
  64. pycityagent/tools/tool.py +93 -69
  65. pycityagent/utils/avro_schema.py +2 -2
  66. pycityagent/utils/parsers/code_block_parser.py +1 -1
  67. pycityagent/utils/parsers/json_parser.py +2 -2
  68. pycityagent/utils/parsers/parser_base.py +2 -2
  69. pycityagent/workflow/block.py +64 -13
  70. pycityagent/workflow/prompt.py +31 -23
  71. pycityagent/workflow/trigger.py +91 -24
  72. {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/METADATA +2 -2
  73. pycityagent-2.0.0a67.dist-info/RECORD +97 -0
  74. pycityagent/environment/interact/__init__.py +0 -0
  75. pycityagent/environment/interact/interact.py +0 -198
  76. pycityagent/environment/message/__init__.py +0 -0
  77. pycityagent/environment/sence/__init__.py +0 -0
  78. pycityagent/environment/sence/static.py +0 -416
  79. pycityagent/environment/sidecar/__init__.py +0 -8
  80. pycityagent/environment/sidecar/sidecarv2.py +0 -109
  81. pycityagent/environment/sim/economy_services.py +0 -192
  82. pycityagent/metrics/utils/const.py +0 -0
  83. pycityagent-2.0.0a66.dist-info/RECORD +0 -105
  84. {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/LICENSE +0 -0
  85. {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/WHEEL +0 -0
  86. {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/entry_points.txt +0 -0
  87. {pycityagent-2.0.0a66.dist-info → pycityagent-2.0.0a67.dist-info}/top_level.txt +0 -0
@@ -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
- CitizenAgent: 城市居民智能体类及其定义
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 Agent to Simulator
94
+ Bind the agent to the Traffic Simulator.
59
95
 
60
- Args:
61
- person_template (dict, optional): The person template in dict format. Defaults to PersonService.default_dict_person().
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
- InstitutionAgent: Institution agent class and definition
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
- try:
214
- nominal_gdp = await _status.get("nominal_gdp")
215
- except:
216
- nominal_gdp = []
217
- try:
218
- real_gdp = await _status.get("real_gdp")
219
- except:
220
- real_gdp = []
221
- try:
222
- unemployment = await _status.get("unemployment")
223
- except:
224
- unemployment = []
225
- try:
226
- wages = await _status.get("wages")
227
- except:
228
- wages = []
229
- try:
230
- prices = await _status.get("prices")
231
- except:
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
- Args:
297
- agent_uuids: 目标智能体UUID列表
298
- target: 要收集的信息类型
394
+ - **Returns**:
395
+ - `list[dict]`: A list of dictionaries containing the collected responses.
299
396
 
300
- Returns:
301
- list[dict]: 收集到的所有响应
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 = {}