pycityagent 1.0.0__py3-none-any.whl → 2.0.0a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. pycityagent/__init__.py +7 -3
  2. pycityagent/agent.py +180 -284
  3. pycityagent/economy/__init__.py +5 -0
  4. pycityagent/economy/econ_client.py +307 -0
  5. pycityagent/environment/__init__.py +7 -0
  6. pycityagent/environment/interact/interact.py +141 -0
  7. pycityagent/environment/sence/__init__.py +0 -0
  8. pycityagent/{brain → environment/sence}/static.py +1 -1
  9. pycityagent/environment/sidecar/__init__.py +8 -0
  10. pycityagent/environment/sidecar/sidecarv2.py +109 -0
  11. pycityagent/environment/sim/__init__.py +29 -0
  12. pycityagent/environment/sim/aoi_service.py +38 -0
  13. pycityagent/environment/sim/client.py +126 -0
  14. pycityagent/environment/sim/clock_service.py +43 -0
  15. pycityagent/environment/sim/economy_services.py +191 -0
  16. pycityagent/environment/sim/lane_service.py +110 -0
  17. pycityagent/environment/sim/light_service.py +120 -0
  18. pycityagent/environment/sim/person_service.py +294 -0
  19. pycityagent/environment/sim/road_service.py +38 -0
  20. pycityagent/environment/sim/sim_env.py +145 -0
  21. pycityagent/environment/sim/social_service.py +58 -0
  22. pycityagent/environment/simulator.py +320 -0
  23. pycityagent/environment/utils/__init__.py +10 -0
  24. pycityagent/environment/utils/base64.py +16 -0
  25. pycityagent/environment/utils/const.py +242 -0
  26. pycityagent/environment/utils/geojson.py +26 -0
  27. pycityagent/environment/utils/grpc.py +57 -0
  28. pycityagent/environment/utils/map_utils.py +157 -0
  29. pycityagent/environment/utils/port.py +11 -0
  30. pycityagent/environment/utils/protobuf.py +39 -0
  31. pycityagent/llm/__init__.py +6 -0
  32. pycityagent/llm/embedding.py +136 -0
  33. pycityagent/llm/llm.py +430 -0
  34. pycityagent/llm/llmconfig.py +15 -0
  35. pycityagent/llm/utils.py +6 -0
  36. pycityagent/memory/__init__.py +11 -0
  37. pycityagent/memory/const.py +41 -0
  38. pycityagent/memory/memory.py +453 -0
  39. pycityagent/memory/memory_base.py +168 -0
  40. pycityagent/memory/profile.py +165 -0
  41. pycityagent/memory/self_define.py +165 -0
  42. pycityagent/memory/state.py +173 -0
  43. pycityagent/memory/utils.py +27 -0
  44. pycityagent/message/__init__.py +0 -0
  45. pycityagent/simulation/__init__.py +7 -0
  46. pycityagent/simulation/interview.py +36 -0
  47. pycityagent/simulation/simulation.py +352 -0
  48. pycityagent/simulation/survey/__init__.py +9 -0
  49. pycityagent/simulation/survey/manager.py +67 -0
  50. pycityagent/simulation/survey/models.py +49 -0
  51. pycityagent/simulation/ui/__init__.py +3 -0
  52. pycityagent/simulation/ui/interface.py +602 -0
  53. pycityagent/utils/__init__.py +0 -0
  54. pycityagent/utils/decorators.py +89 -0
  55. pycityagent/utils/parsers/__init__.py +12 -0
  56. pycityagent/utils/parsers/code_block_parser.py +37 -0
  57. pycityagent/utils/parsers/json_parser.py +86 -0
  58. pycityagent/utils/parsers/parser_base.py +60 -0
  59. pycityagent/workflow/__init__.py +24 -0
  60. pycityagent/workflow/block.py +164 -0
  61. pycityagent/workflow/prompt.py +72 -0
  62. pycityagent/workflow/tool.py +246 -0
  63. pycityagent/workflow/trigger.py +150 -0
  64. pycityagent-2.0.0a2.dist-info/METADATA +208 -0
  65. pycityagent-2.0.0a2.dist-info/RECORD +69 -0
  66. {pycityagent-1.0.0.dist-info → pycityagent-2.0.0a2.dist-info}/WHEEL +1 -2
  67. pycityagent/ac/__init__.py +0 -6
  68. pycityagent/ac/ac.py +0 -50
  69. pycityagent/ac/action.py +0 -14
  70. pycityagent/ac/controled.py +0 -13
  71. pycityagent/ac/converse.py +0 -31
  72. pycityagent/ac/idle.py +0 -17
  73. pycityagent/ac/shop.py +0 -80
  74. pycityagent/ac/trip.py +0 -37
  75. pycityagent/brain/__init__.py +0 -10
  76. pycityagent/brain/brain.py +0 -52
  77. pycityagent/brain/brainfc.py +0 -10
  78. pycityagent/brain/memory.py +0 -541
  79. pycityagent/brain/persistence/social.py +0 -1
  80. pycityagent/brain/persistence/spatial.py +0 -14
  81. pycityagent/brain/reason/shop.py +0 -37
  82. pycityagent/brain/reason/social.py +0 -148
  83. pycityagent/brain/reason/trip.py +0 -67
  84. pycityagent/brain/reason/user.py +0 -122
  85. pycityagent/brain/retrive/social.py +0 -6
  86. pycityagent/brain/scheduler.py +0 -408
  87. pycityagent/brain/sence.py +0 -375
  88. pycityagent/cc/__init__.py +0 -5
  89. pycityagent/cc/cc.py +0 -102
  90. pycityagent/cc/conve.py +0 -6
  91. pycityagent/cc/idle.py +0 -20
  92. pycityagent/cc/shop.py +0 -6
  93. pycityagent/cc/trip.py +0 -13
  94. pycityagent/cc/user.py +0 -13
  95. pycityagent/hubconnector/__init__.py +0 -3
  96. pycityagent/hubconnector/hubconnector.py +0 -137
  97. pycityagent/image/__init__.py +0 -3
  98. pycityagent/image/image.py +0 -158
  99. pycityagent/simulator.py +0 -161
  100. pycityagent/st/__init__.py +0 -4
  101. pycityagent/st/st.py +0 -96
  102. pycityagent/urbanllm/__init__.py +0 -3
  103. pycityagent/urbanllm/urbanllm.py +0 -132
  104. pycityagent-1.0.0.dist-info/LICENSE +0 -21
  105. pycityagent-1.0.0.dist-info/METADATA +0 -181
  106. pycityagent-1.0.0.dist-info/RECORD +0 -48
  107. pycityagent-1.0.0.dist-info/top_level.txt +0 -1
  108. /pycityagent/{brain/persistence/__init__.py → config.py} +0 -0
  109. /pycityagent/{brain/reason → environment/interact}/__init__.py +0 -0
  110. /pycityagent/{brain/retrive → environment/message}/__init__.py +0 -0
pycityagent/__init__.py CHANGED
@@ -1,4 +1,8 @@
1
- from .simulator import Simulator
2
- from .agent import Agent
1
+ """
2
+ Pycityagent: 城市智能体构建框架
3
+ """
3
4
 
4
- __all__ = [Simulator, Agent]
5
+ from .agent import Agent, CitizenAgent, InstitutionAgent
6
+ from .environment import Simulator
7
+
8
+ __all__ = ["Agent", "Simulator", "CitizenAgent", "InstitutionAgent"]
pycityagent/agent.py CHANGED
@@ -1,318 +1,214 @@
1
+ """智能体模板类及其定义"""
2
+
1
3
  from abc import ABC, abstractmethod
2
- from typing import Optional, Union
3
- import PIL.Image as Image
4
- from PIL.Image import Image
5
- import asyncio
6
- import time
7
- from pycitysim.sim import CityClient
8
-
9
- from pycityagent.urbanllm import UrbanLLM
10
- from .urbanllm import UrbanLLM
11
- from .brain.brain import Brain
12
- from .hubconnector.hubconnector import HubConnector
13
- from .image.image import AgentImage
14
- from .ac.ac import ActionController
15
- from .cc.cc import CommondController
16
- from .st.st import StateTransformer
17
-
18
-
19
- class Template:
20
- """
21
- The basic template of Agent
22
- """
23
- def __init__(self, name, server, soul:UrbanLLM=None, simulator=None, id:int=None) -> None:
24
- self.agent_name = name
25
- self._client = CityClient(server)
26
- self._soul = soul
27
- self._simulator = simulator
28
- self._id = id
4
+ from datetime import datetime
5
+ from enum import Enum
6
+ from typing import Dict, List, Optional
29
7
 
30
- def add_soul(self, llm_engine:UrbanLLM):
31
- """
32
- 为Agent添加soul(UrbanLLM)
33
- Add soul for Agent
8
+ from .economy import EconomyClient
9
+ from .environment import Simulator
10
+ from .llm import LLM
11
+ from .memory import Memory
34
12
 
35
- Args:
36
- - llm_engine (UrbanLLM): the soul
37
- """
38
- self._soul = llm_engine
39
13
 
40
- def add_simulator(self, simulator):
41
- """
42
- 添加关联模拟器
43
- Add related simulator
14
+ class AgentType(Enum):
15
+ """
16
+ Agent类型
44
17
 
45
- Args:
46
- - simulator (Simulator): the Simulator object
47
- """
48
- self._simulator = simulator
18
+ - Citizen, Citizen type agent
19
+ - Institution, Orgnization or institution type agent
20
+ """
49
21
 
50
- @abstractmethod
51
- def Step(self):
52
- """模拟器执行接口"""
22
+ Unspecified = "Unspecified"
23
+ Citizen = "Citizen"
24
+ Institution = "Institution"
53
25
 
54
- class Agent(Template):
26
+
27
+ class Agent(ABC):
55
28
  """
56
- Agent
29
+ Agent base class
57
30
  """
31
+
58
32
  def __init__(
59
- self,
60
- name:str,
61
- server:str,
62
- soul:UrbanLLM=None,
63
- simulator=None,
64
- id:int=None,
65
- base=None,
66
- motion=None,
67
- scratch_file:str=None,
68
- selfie:bool = False,
69
- connect_to_hub:bool=False,
70
- hub_url:str=None,
71
- app_id:int=None,
72
- app_secret:str=None,
73
- profile_img:str=None
74
- ) -> None:
75
- super().__init__(name, server, soul, simulator, id)
76
- self.base = base
77
- """
78
- Agent/Person的基本属性, Agent指被代理的Person, Person指模拟器中的背景人
79
- The base attributes of Agent/Person. Agent is the Person being represented. Persons are background persons in simulator
80
- - https://cityproto.sim.fiblab.net/#city.agent.v2.Agent
81
- """
82
- self.motion = motion
83
- """
84
- Agent/Person的运动信息
85
- The motion information of Agent/Person
86
- - https://cityproto.sim.fiblab.net/#city.agent.v2.AgentMotion
87
- """
88
- if connect_to_hub:
89
- self._hub_connector = HubConnector(
90
- hub_url=hub_url,
91
- app_id=app_id,
92
- app_secret=app_secret,
93
- agent=self,
94
- profile_img=profile_img
95
- )
96
- else:
97
- self._hub_connector = None
98
- self._image = AgentImage(self, scratch_file, selfie)
99
- """
100
- Agent画像
101
- The Agent's Image
33
+ self,
34
+ name: str,
35
+ type: AgentType = AgentType.Unspecified,
36
+ llm_client: Optional[LLM] = None,
37
+ economy_client: Optional[EconomyClient] = None,
38
+ simulator: Optional[Simulator] = None,
39
+ memory: Optional[Memory] = None,
40
+ ) -> None:
102
41
  """
103
- self._brain = Brain(self)
104
- """
105
- Agent的大脑
106
- The Agent's Brain
107
- """
108
- self._ac = ActionController(self)
109
- """
110
- Agent的行为控制器
111
- The Agent's ActionController
112
- """
113
- self._cc = CommondController(self)
114
- """
115
- Agent的命令控制器
116
- The Agent's CommondController
117
- """
118
- self._st = StateTransformer()
119
- """
120
- 与Agent关联的状态转移器
121
- The related StateTransformer
122
- """
123
- # * 默认trip构建
124
- self.Scheduler.schedule_init()
125
-
126
- def ConnectToHub(self, config:dict):
127
- """
128
- 与AppHub构建连接
129
- Connect to AppHub
42
+ Initialize the Agent.
130
43
 
131
44
  Args:
132
- - config (dict): the config dict of AppHub
133
- """
134
- profile_img = None
135
- if 'profile_image' in config.keys():
136
- profile_img = config['profile_image']
137
- self._hub_connector = HubConnector(
138
- hub_url=config['hub_url'],
139
- app_id=config['app_id'],
140
- app_secret=config['app_secret'],
141
- agent=self,
142
- profile_img=profile_img
143
- )
144
-
145
- def enable_streetview(self):
146
- """
147
- 开启街景相关功能
148
- Enable Streetview function
149
- """
150
- self._brain.Sence.enable_streeview = True
45
+ name (str): The name of the agent.
46
+ type (AgentType): The type of the agent. Defaults to `AgentType.Unspecified`
47
+ llm_client (LLM): The language model client. Defaults to None.
48
+ economy_client (EconomyClient): The `EconomySim` client. Defaults to None.
49
+ simulator (Simulator, optional): The simulator object. Defaults to None.
50
+ memory (Memory, optional): The memory of the agent. Defaults to None.
51
+ """
52
+ self._name = name
53
+ self._type = type
54
+ self._llm_client = llm_client
55
+ self._economy_client = economy_client
56
+ self._simulator = simulator
57
+ self._memory = memory
58
+ self._has_bound_to_simulator = False
59
+ self._interview_history: List[Dict] = [] # 存储采访历史
151
60
 
152
- def disable_streetview(self):
61
+ def set_memory(self, memory: Memory):
153
62
  """
154
- 关闭街景相关功能
155
- Disable Streetview function
63
+ Set the memory of the agent.
156
64
  """
157
- self._brain.Sence.enable_streeview = False
65
+ self._memory = memory
158
66
 
159
- def enable_user_interaction(self):
67
+ def set_simulator(self, simulator: Simulator):
160
68
  """
161
- 开启用户交互功能(即在OpenCity控制台中与Agent进行交互)
162
- Enable User Interaction function. The User Interaction function is the ability to interact with the related agent in OpenCity website console.
69
+ Set the simulator of the agent.
163
70
  """
164
- self._brain.Memory.Working.enable_user_interaction = True
71
+ self._simulator = simulator
165
72
 
166
- def disable_user_interaction(self):
73
+ def set_economy_client(self, economy_client: EconomyClient):
167
74
  """
168
- 关闭用户交互功能
169
- Disable User Interaction function
75
+ Set the economy_client of the agent.
170
76
  """
171
- self._brain.Memory.Working.enable_user_interaction = False
77
+ self._economy_client = economy_client
172
78
 
173
- def enable_economy_behavior(self):
174
- """
175
- 开启经济模拟相关功能(例如购物)
176
- Enable Economy function. Shopping for instance.
177
- """
178
- self.Brain.Memory.Working.enable_economy = True
79
+ @property
80
+ def LLM(self):
81
+ """The Agent's LLM"""
82
+ if self._llm_client is None:
83
+ raise RuntimeError(
84
+ f"LLM access before assignment, please `set_llm_client` first!"
85
+ )
86
+ return self._llm_client
179
87
 
180
- def disable_economy_behavior(self):
181
- """
182
- 关闭经济模拟相关功能
183
- Disable Economy function
184
- """
185
- self.Brain.Memory.Working.enable_economy = False
88
+ @property
89
+ def economy_client(self):
90
+ """The Agent's EconomyClient"""
91
+ if self._economy_client is None:
92
+ raise RuntimeError(
93
+ f"EconomyClient access before assignment, please `set_economy_client` first!"
94
+ )
95
+ return self._economy_client
186
96
 
187
- def enable_social_behavior(self):
188
- """
189
- 开启社交相关功能
190
- Enable Social function
191
- """
192
- self.Brain.Memory.Working.enable_social = True
97
+ @property
98
+ def memory(self):
99
+ """The Agent's Memory"""
100
+ if self._memory is None:
101
+ raise RuntimeError(
102
+ f"Memory access before assignment, please `set_memory` first!"
103
+ )
104
+ return self._memory
193
105
 
194
- def diable_social_behavior(self):
195
- """
196
- 关闭社交相关功能
197
- Disable Social function
198
- """
199
- self.Brain.Memory.Working.enable_social = False
106
+ @property
107
+ def simulator(self):
108
+ """The Simulator"""
109
+ if self._simulator is None:
110
+ raise RuntimeError(
111
+ f"Simulator access before assignment, please `set_simulator` first!"
112
+ )
113
+ return self._simulator
200
114
 
201
- async def Pause(self):
202
- """
203
- 暂停Agent行为使Agent进入'pause'状态
204
- Pause the Agent, making the agent 'pause'
115
+ async def generate_response(self, question: str) -> str:
116
+ """生成回答
205
117
 
206
- """
207
- req = {'person_id': self.base['id'], 'schedules': []}
208
- await self._client.person_service.SetSchedule(req)
209
- self.Scheduler.unset_schedule()
210
- self._st.trigger('pause')
118
+ 基于智能体的记忆和当前状态,生成对问题的回答。
211
119
 
212
- async def Active(self):
213
- """
214
- 恢复Agent行为
215
- Recover from 'pause'
216
- """
217
- self._st.pause_back()
120
+ Args:
121
+ question: 需要回答的问题
122
+
123
+ Returns:
124
+ str: 智能体的回答
125
+ """
126
+ dialog = []
127
+
128
+ # 添加系统提示
129
+ system_prompt = f"请以第一人称的方式回答问题,保持回答简洁明了。"
130
+ dialog.append({"role": "system", "content": system_prompt})
131
+
132
+ # 添加记忆上下文
133
+ if self._memory:
134
+ relevant_memories = await self._memory.search(question)
135
+ if relevant_memories:
136
+ dialog.append(
137
+ {
138
+ "role": "system",
139
+ "content": f"基于以下记忆回答问题:\n{relevant_memories}",
140
+ }
141
+ )
142
+
143
+ # 添加用户问题
144
+ dialog.append({"role": "user", "content": question})
145
+
146
+ # 使用LLM生成回答
147
+ if not self._llm_client:
148
+ return "抱歉,我现在无法回答问题。"
149
+
150
+ response = await self._llm_client.atext_request(dialog) # type:ignore
151
+
152
+ # 记录采访历史
153
+ self._interview_history.append(
154
+ {
155
+ "timestamp": datetime.now().isoformat(),
156
+ "question": question,
157
+ "response": response,
158
+ }
159
+ )
218
160
 
219
- async def Run(self, round:int=1, interval:int=1, log:bool=True):
220
- """
221
- Agent执行入口
222
- The Agent Run entrance
161
+ return response # type:ignore
223
162
 
224
- Args:
225
- - round (int): 执行步数. The steps to run.
226
- - interval (int): 步与步之间的执行间隔, 单位秒. The interval between steps, second.
227
- - log (bool): 是否输出log信息, 默认为True. Whether console log message, default: True
228
- """
229
- if self._soul == None:
230
- print("Do not add soul yet. Try add_soul(UrbanLLM)")
231
- await self.Step(log)
232
- for i in range(0, round-1):
233
- time.sleep(interval)
234
- await self.Step(log)
235
-
236
- async def Step(self, log:bool):
237
- """
238
- 单步Agent执行流
239
- Single step entrance
240
- (Not recommended, use Run() method)
163
+ def get_interview_history(self) -> List[Dict]:
164
+ """获取采访历史记录"""
165
+ return self._interview_history
241
166
 
242
- Args:
243
- - log (bool): 是否输出log信息. Whether console log message
244
- """
245
- if self.state != 'paused':
246
- # * 1. 模拟器时间更新
247
- await self._simulator.GetTime()
248
- # * 2. 拉取Agent最新状态
249
- resp = await self._client.person_service.GetPerson({'person_id':self._id})
250
- self.base = resp['base']
251
- self.motion = resp['motion']
252
- # * 3. Brain工作流
253
- await self._brain.Run()
254
- # * 4. Commond Controller工作流
255
- commond = await self._cc.Run()
256
- # * 5. State Transformer工作流
257
- self._st.trigger(commond)
258
- # * 6. Action Controller工作流
259
- await self._ac.Run()
260
- if log:
261
- print(f"---------------------- SIM TIME: {self._simulator.time} ----------------------")
262
- self.show_yourself()
263
-
264
- def show_yourself(self):
265
- """
266
- Log信息输出
267
- Pring log message
268
- """
269
- print(f"【State Message】: {self.state}")
270
- motion_message = ''''''
271
- motion_message += f'''行为状态: {self.motion['status']}, '''
272
- if 'lane_position' in self.motion['position'].keys():
273
- motion_message += f'''位置信息: lane-{self.motion['position']['lane_position']['lane_id']}'''
274
- else:
275
- motion_message += f'''位置信息: aoi-{self.motion['position']['aoi_position']['aoi_id']}'''
276
- motion_message += f'''-[x: {self.motion['position']['xy_position']['x']}, y: {self.motion['position']['xy_position']['y']}]'''
277
- print(f'【Simulator Motion Message】: \n{motion_message}')
278
- print(self.Scheduler)
279
-
280
- @property
281
- def Image(self):
282
- """The Agent's Image"""
283
- return self._image
284
-
285
- @property
286
- def Soul(self):
287
- """The Agent's Soul(UrbanLLM)"""
288
- return self._soul
289
-
290
- @property
291
- def Brain(self):
292
- """The Agent's Brain"""
293
- return self._brain
294
-
295
- @property
296
- def ActionController(self):
297
- """The Agents's ActionController"""
298
- return self._ac
167
+ @abstractmethod
168
+ async def forward(self) -> None:
169
+ """智能体行为逻辑"""
170
+ raise NotImplementedError
299
171
 
300
- @property
301
- def Scheduler(self):
302
- """The Agent's Scheduler"""
303
- return self._brain.Memory.Working.scheduler
304
-
305
- @property
306
- def state(self):
307
- """The state of the Agent"""
308
- return self._st.state
309
-
310
- @property
311
- def StateTransformer(self):
312
- """The StateTransformer of the Agent"""
313
- return self._st
314
172
 
315
- @property
316
- def Hub(self):
317
- """The connected AppHub"""
318
- return self._hub_connector
173
+ class CitizenAgent(Agent):
174
+ """
175
+ CitizenAgent: 城市居民智能体类及其定义
176
+ """
177
+
178
+ def __init__(
179
+ self,
180
+ name: str,
181
+ llm_client: Optional[LLM] = None,
182
+ simulator: Optional[Simulator] = None,
183
+ memory: Optional[Memory] = None,
184
+ ) -> None:
185
+ super().__init__(
186
+ name,
187
+ AgentType.Citizen,
188
+ llm_client,
189
+ None,
190
+ simulator,
191
+ memory,
192
+ )
193
+
194
+
195
+ class InstitutionAgent(Agent):
196
+ """
197
+ InstitutionAgent: 机构智能体类及其定义
198
+ """
199
+
200
+ def __init__(
201
+ self,
202
+ name: str,
203
+ llm_client: Optional[LLM] = None,
204
+ simulator: Optional[Simulator] = None,
205
+ memory: Optional[Memory] = None,
206
+ ) -> None:
207
+ super().__init__(
208
+ name,
209
+ AgentType.Institution,
210
+ llm_client,
211
+ None,
212
+ simulator,
213
+ memory,
214
+ )
@@ -0,0 +1,5 @@
1
+ from .econ_client import EconomyClient
2
+
3
+ __all__ = [
4
+ "EconomyClient",
5
+ ]