pycityagent 1.0.0__tar.gz → 1.1.0__tar.gz

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 (72) hide show
  1. {pycityagent-1.0.0 → pycityagent-1.1.0}/PKG-INFO +46 -18
  2. {pycityagent-1.0.0 → pycityagent-1.1.0}/README.md +44 -16
  3. pycityagent-1.1.0/pycityagent/__init__.py +6 -0
  4. pycityagent-1.1.0/pycityagent/ac/__init__.py +8 -0
  5. pycityagent-1.1.0/pycityagent/ac/ac.py +67 -0
  6. pycityagent-1.1.0/pycityagent/ac/action.py +55 -0
  7. pycityagent-1.1.0/pycityagent/ac/action_stream.py +25 -0
  8. pycityagent-1.1.0/pycityagent/ac/citizen_actions/controled.py +16 -0
  9. pycityagent-1.1.0/pycityagent/ac/citizen_actions/converse.py +34 -0
  10. pycityagent-1.1.0/pycityagent/ac/citizen_actions/idle.py +20 -0
  11. pycityagent-1.1.0/pycityagent/ac/citizen_actions/shop.py +82 -0
  12. pycityagent-1.1.0/pycityagent/ac/citizen_actions/trip.py +41 -0
  13. pycityagent-1.1.0/pycityagent/ac/hub_actions.py +93 -0
  14. pycityagent-1.1.0/pycityagent/ac/sim_actions.py +80 -0
  15. pycityagent-1.1.0/pycityagent/agent.py +272 -0
  16. pycityagent-1.1.0/pycityagent/agent_citizen.py +158 -0
  17. pycityagent-1.1.0/pycityagent/agent_func.py +115 -0
  18. pycityagent-1.1.0/pycityagent/brain/__init__.py +10 -0
  19. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/memory.py +200 -106
  20. pycityagent-1.1.0/pycityagent/brain/sence.py +669 -0
  21. pycityagent-1.1.0/pycityagent/cc/__init__.py +5 -0
  22. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/cc/cc.py +40 -36
  23. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/hubconnector/hubconnector.py +23 -31
  24. pycityagent-1.1.0/pycityagent/image/__init__.py +3 -0
  25. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/image/image.py +48 -44
  26. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/simulator.py +39 -39
  27. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/st/st.py +44 -7
  28. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent.egg-info/PKG-INFO +46 -18
  29. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent.egg-info/SOURCES.txt +10 -0
  30. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent.egg-info/requires.txt +1 -1
  31. {pycityagent-1.0.0 → pycityagent-1.1.0}/pyproject.toml +1 -1
  32. pycityagent-1.0.0/pycityagent/__init__.py +0 -4
  33. pycityagent-1.0.0/pycityagent/ac/__init__.py +0 -6
  34. pycityagent-1.0.0/pycityagent/ac/ac.py +0 -50
  35. pycityagent-1.0.0/pycityagent/ac/action.py +0 -14
  36. pycityagent-1.0.0/pycityagent/agent.py +0 -318
  37. pycityagent-1.0.0/pycityagent/brain/__init__.py +0 -10
  38. pycityagent-1.0.0/pycityagent/brain/sence.py +0 -375
  39. pycityagent-1.0.0/pycityagent/cc/__init__.py +0 -5
  40. pycityagent-1.0.0/pycityagent/image/__init__.py +0 -3
  41. {pycityagent-1.0.0 → pycityagent-1.1.0}/LICENSE +0 -0
  42. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/ac/controled.py +0 -0
  43. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/ac/converse.py +0 -0
  44. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/ac/idle.py +0 -0
  45. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/ac/shop.py +0 -0
  46. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/ac/trip.py +0 -0
  47. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/brain.py +0 -0
  48. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/brainfc.py +0 -0
  49. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/persistence/__init__.py +0 -0
  50. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/persistence/social.py +0 -0
  51. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/persistence/spatial.py +0 -0
  52. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/reason/__init__.py +0 -0
  53. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/reason/shop.py +0 -0
  54. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/reason/social.py +0 -0
  55. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/reason/trip.py +0 -0
  56. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/reason/user.py +0 -0
  57. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/retrive/__init__.py +0 -0
  58. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/retrive/social.py +0 -0
  59. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/scheduler.py +0 -0
  60. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/brain/static.py +0 -0
  61. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/cc/conve.py +0 -0
  62. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/cc/idle.py +0 -0
  63. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/cc/shop.py +0 -0
  64. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/cc/trip.py +0 -0
  65. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/cc/user.py +0 -0
  66. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/hubconnector/__init__.py +0 -0
  67. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/st/__init__.py +0 -0
  68. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/urbanllm/__init__.py +0 -0
  69. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent/urbanllm/urbanllm.py +0 -0
  70. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent.egg-info/dependency_links.txt +0 -0
  71. {pycityagent-1.0.0 → pycityagent-1.1.0}/pycityagent.egg-info/top_level.txt +0 -0
  72. {pycityagent-1.0.0 → pycityagent-1.1.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycityagent
3
- Version: 1.0.0
3
+ Version: 1.1.0
4
4
  Summary: LLM-based城市模拟器agent构建库
5
5
  Author-email: Yuwei Yan <pinkgranite86@gmail.com>
6
6
  License: MIT License
@@ -39,7 +39,7 @@ Requires-Dist: geojson>=3.1.0
39
39
  Requires-Dist: numpy>=1.26.3
40
40
  Requires-Dist: openai>=1.8.0
41
41
  Requires-Dist: Pillow>=10.2.0
42
- Requires-Dist: pycitysim>=1.8.0
42
+ Requires-Dist: pycitysim>=1.12.2
43
43
  Requires-Dist: citystreetview>=1.1.0
44
44
  Requires-Dist: PyYAML>=6.0.1
45
45
  Requires-Dist: Requests>=2.31.0
@@ -92,10 +92,12 @@ citysim_request:
92
92
  map_request:
93
93
  mongo_coll: map_beijing_extend_20240205
94
94
  cache_dir: ./cache
95
+ route_request:
96
+ server: http://api-opencity-2x.fiblab.net:58082
95
97
  streetview_request:
96
98
  engine: baidumap / googlemap
97
- mapAK: your baidumap AK (if baidumap)
98
- proxy: your googlemap proxy (if googlemap, optional)
99
+ mapAK: baidumap api-key (if you use baidumap engine)
100
+ proxy: googlemap proxy (if you use googlemap engine)
99
101
 
100
102
  apphub_request:
101
103
  hub_url: https://api-opencity-2x.fiblab.net:58080
@@ -106,31 +108,56 @@ apphub_request:
106
108
  - Forget about **citysim_request**, let's focus on the other two.
107
109
 
108
110
  #### LLM_REQUEST
109
- - As you can tell, the whole CityAgent is based on the LLM, by now, there are three different parts of config items: **text_request**, **img_understand_request** and **img_generate_request**
111
+ - As you can see, the whole CityAgent is based on the LLM, by now, there are three different parts of config items: **text_request**, **img_understand_request** and **img_generate_request**
110
112
  - By now, we support [**qwen**](https://tongyi.aliyun.com/) and [**openai**](https://openai.com/)
111
113
  - `Notice: Our environments are basically conducted with qwen. If you prefer to use openai, then you may encounter hardships. AND fell free to issue us.`
112
114
  - Get your **api_key** and chooce your **model**s
113
115
 
114
- ### CITYSIM_REQUEST
115
- - There are no need to change the 'simulator' and 'map_request' config
116
- - 'streetview_request': this is the config used for streetview
117
- - By now, we support 'baidumap' and 'googlemap'
118
- - If you use 'baidumap', then you need to apply for a mapAK
119
- - If you use 'googlemap', then you can config your own proxy by 'proxy' attribute
116
+ #### CITYSIM_REQUEST
117
+ - Most of the configuration options in this part are determined, such as **simulator.server**, **map_request.mongo_coll**, **route_request.server**
118
+ - **map_request.cache_dir**: used for storing map data your machine, you can justify the target dir as you wish (**create the dir first**)
119
+ - **streetview_request**: used for obtaining streetview images, by now, we support baidumap engine and googlemap engine
120
+ - if you choose baidumap engine, you need to get a baidumap api-key
121
+ ``` yaml
122
+ streetview_request:
123
+ engine: baidumap
124
+ mapAK: xxxx
125
+ ```
126
+ - if you choose googlemap engine, you need to provide your proxy address, for example:
127
+ ``` yaml
128
+ streetview_request:
129
+ engine: googlemap
130
+ proxy:
131
+ http: http://xxxx
132
+ https: https://xxxx
133
+ ```
120
134
 
121
135
  #### APPHUB_REQUEST
122
- - This is basically used to connect with the backend.
136
+ - Used for creating the connection between backend server and client.
123
137
  - Put your **app_id** and **app_secret** here.
138
+ - Create your account and apply in [Opencity website](https://opencity.fiblab.net/)
124
139
 
125
140
  ### Installation
126
- - Install from **pip** easily.
127
- ```shell
128
- pip install pycityagent
129
- ```
141
+ #### PyPI Installation
142
+ - Install from **pip** easily.
143
+ ```shell
144
+ pip install pycityagent
145
+ ```
146
+
147
+ #### Install from source code
148
+ - Clone this repo
149
+ - Install required packages
150
+ ``` shell
151
+ pip install -r requirements.txt
152
+ ```
153
+ - Install **libGL.so.1**, if you ara using Linux with a suitable package manager: (apt for instance)
154
+ ``` shell
155
+ apt-get install libgl1
156
+ ```
130
157
 
131
158
  ### CODE and RUN
132
159
  - Check the **example** folder and copy files from it (`Remember replace the config file`)
133
- - Look at the Demo:
160
+ - Look at the Demo: (A citizen Agent demo)
134
161
  ```python
135
162
  import yaml
136
163
  from pycityagent.simulator import Simulator
@@ -147,7 +174,7 @@ async def main():
147
174
  smi = Simulator(config['citysim_request'])
148
175
 
149
176
  # get the person by person_id, return agent
150
- agent = await smi.GetAgent("name_of_agent", 8)
177
+ agent = await smi.GetCitizenAgent("name_of_agent", 8)
151
178
 
152
179
  # Help you build unique agent by scratch/profile
153
180
  agent.Image.load_scratch('scratch_template.json')
@@ -158,6 +185,7 @@ async def main():
158
185
 
159
186
  # Connect to apphub so you can interact with your agent in front end
160
187
  agent.ConnectToHub(config['apphub_request'])
188
+ agent.Bind()
161
189
 
162
190
  # Creat the soul (a LLM processor actually)
163
191
  llmConfig = LLMConfig(config['llm_request'])
@@ -45,10 +45,12 @@ citysim_request:
45
45
  map_request:
46
46
  mongo_coll: map_beijing_extend_20240205
47
47
  cache_dir: ./cache
48
+ route_request:
49
+ server: http://api-opencity-2x.fiblab.net:58082
48
50
  streetview_request:
49
51
  engine: baidumap / googlemap
50
- mapAK: your baidumap AK (if baidumap)
51
- proxy: your googlemap proxy (if googlemap, optional)
52
+ mapAK: baidumap api-key (if you use baidumap engine)
53
+ proxy: googlemap proxy (if you use googlemap engine)
52
54
 
53
55
  apphub_request:
54
56
  hub_url: https://api-opencity-2x.fiblab.net:58080
@@ -59,31 +61,56 @@ apphub_request:
59
61
  - Forget about **citysim_request**, let's focus on the other two.
60
62
 
61
63
  #### LLM_REQUEST
62
- - As you can tell, the whole CityAgent is based on the LLM, by now, there are three different parts of config items: **text_request**, **img_understand_request** and **img_generate_request**
64
+ - As you can see, the whole CityAgent is based on the LLM, by now, there are three different parts of config items: **text_request**, **img_understand_request** and **img_generate_request**
63
65
  - By now, we support [**qwen**](https://tongyi.aliyun.com/) and [**openai**](https://openai.com/)
64
66
  - `Notice: Our environments are basically conducted with qwen. If you prefer to use openai, then you may encounter hardships. AND fell free to issue us.`
65
67
  - Get your **api_key** and chooce your **model**s
66
68
 
67
- ### CITYSIM_REQUEST
68
- - There are no need to change the 'simulator' and 'map_request' config
69
- - 'streetview_request': this is the config used for streetview
70
- - By now, we support 'baidumap' and 'googlemap'
71
- - If you use 'baidumap', then you need to apply for a mapAK
72
- - If you use 'googlemap', then you can config your own proxy by 'proxy' attribute
69
+ #### CITYSIM_REQUEST
70
+ - Most of the configuration options in this part are determined, such as **simulator.server**, **map_request.mongo_coll**, **route_request.server**
71
+ - **map_request.cache_dir**: used for storing map data your machine, you can justify the target dir as you wish (**create the dir first**)
72
+ - **streetview_request**: used for obtaining streetview images, by now, we support baidumap engine and googlemap engine
73
+ - if you choose baidumap engine, you need to get a baidumap api-key
74
+ ``` yaml
75
+ streetview_request:
76
+ engine: baidumap
77
+ mapAK: xxxx
78
+ ```
79
+ - if you choose googlemap engine, you need to provide your proxy address, for example:
80
+ ``` yaml
81
+ streetview_request:
82
+ engine: googlemap
83
+ proxy:
84
+ http: http://xxxx
85
+ https: https://xxxx
86
+ ```
73
87
 
74
88
  #### APPHUB_REQUEST
75
- - This is basically used to connect with the backend.
89
+ - Used for creating the connection between backend server and client.
76
90
  - Put your **app_id** and **app_secret** here.
91
+ - Create your account and apply in [Opencity website](https://opencity.fiblab.net/)
77
92
 
78
93
  ### Installation
79
- - Install from **pip** easily.
80
- ```shell
81
- pip install pycityagent
82
- ```
94
+ #### PyPI Installation
95
+ - Install from **pip** easily.
96
+ ```shell
97
+ pip install pycityagent
98
+ ```
99
+
100
+ #### Install from source code
101
+ - Clone this repo
102
+ - Install required packages
103
+ ``` shell
104
+ pip install -r requirements.txt
105
+ ```
106
+ - Install **libGL.so.1**, if you ara using Linux with a suitable package manager: (apt for instance)
107
+ ``` shell
108
+ apt-get install libgl1
109
+ ```
83
110
 
84
111
  ### CODE and RUN
85
112
  - Check the **example** folder and copy files from it (`Remember replace the config file`)
86
- - Look at the Demo:
113
+ - Look at the Demo: (A citizen Agent demo)
87
114
  ```python
88
115
  import yaml
89
116
  from pycityagent.simulator import Simulator
@@ -100,7 +127,7 @@ async def main():
100
127
  smi = Simulator(config['citysim_request'])
101
128
 
102
129
  # get the person by person_id, return agent
103
- agent = await smi.GetAgent("name_of_agent", 8)
130
+ agent = await smi.GetCitizenAgent("name_of_agent", 8)
104
131
 
105
132
  # Help you build unique agent by scratch/profile
106
133
  agent.Image.load_scratch('scratch_template.json')
@@ -111,6 +138,7 @@ async def main():
111
138
 
112
139
  # Connect to apphub so you can interact with your agent in front end
113
140
  agent.ConnectToHub(config['apphub_request'])
141
+ agent.Bind()
114
142
 
115
143
  # Creat the soul (a LLM processor actually)
116
144
  llmConfig = LLMConfig(config['llm_request'])
@@ -0,0 +1,6 @@
1
+ from .simulator import Simulator
2
+ from .agent import Agent
3
+ from .agent_citizen import CitizenAgent
4
+ from .agent_func import FuncAgent
5
+
6
+ __all__ = [Simulator, Agent, CitizenAgent, FuncAgent]
@@ -0,0 +1,8 @@
1
+ '''Action Control - 最终进行simulator以及AppHub对接'''
2
+
3
+ from .ac import *
4
+ from .action import *
5
+ from .hub_actions import *
6
+ from .sim_actions import *
7
+
8
+ __all__ = [ActionController, Action, HubAction, SimAction, SendUserMessage, SendStreetview, SendPop, PositionUpdate, ShowPath, ShowPosition, SetSchedule, SendAgentMessage]
@@ -0,0 +1,67 @@
1
+ from typing import Any, Optional, Union
2
+ from .action import Action
3
+ from .citizen_actions.trip import TripAction
4
+ from .citizen_actions.shop import ShopAction
5
+ from .citizen_actions.converse import ConverseAction
6
+ from .citizen_actions.controled import ControledAction
7
+ from .citizen_actions.idle import IdleAction
8
+
9
+ class ActionController:
10
+ """
11
+ Agent行为控制器: 与AppHub(simulator)对接
12
+ Agent Controller: Connect with AppHub and Simulator
13
+ Note: Actions are predefined. By now, user defined actions are not supported
14
+ """
15
+ def __init__(self, agent) -> None:
16
+ self._agent = agent
17
+ self.action_chain = {}
18
+ self.reset_ac()
19
+ self._init_actions()
20
+
21
+ async def Run(self):
22
+ agent_state = self._agent.state
23
+ if agent_state in self.action_chain.keys():
24
+ for action in self.action_chain[agent_state]:
25
+ await action.Forward()
26
+
27
+ def clear_ac(self):
28
+ """
29
+ 清空AC
30
+ """
31
+ self.action_chain.clear()
32
+
33
+ def reset_ac(self):
34
+ """
35
+ 重置Action Controller
36
+ Reset action controller
37
+ """
38
+ self.action_chain.clear()
39
+ for state in self._agent._st.machine.states.keys():
40
+ self.action_chain[state] = []
41
+
42
+ def set_ac(self, states:list[str]):
43
+ """
44
+ 设置ac
45
+ """
46
+ self.action_chain.clear()
47
+ for state in states:
48
+ self.action_chain[state] = []
49
+
50
+ def add_actions(self, state:str, actions:Union[Action, list[Action]]):
51
+ """
52
+ 添加Action到目标动作链
53
+ """
54
+ if issubclass(type(actions), Action) or isinstance(actions, Action):
55
+ self.action_chain[state].append(actions)
56
+ else:
57
+ self.action_chain[state] += actions
58
+
59
+ def _init_actions(self):
60
+ """
61
+ 构建初始化动作链——适用于citizen类型的agent
62
+ """
63
+ self.action_chain['trip'] = [TripAction(self._agent)]
64
+ self.action_chain['shop'] = [ShopAction(self._agent)]
65
+ self.action_chain['conve'] = [ConverseAction(self._agent)]
66
+ self.action_chain['controled'] = [ControledAction(self._agent)]
67
+ self.action_chain['idle'] = [IdleAction(self._agent)]
@@ -0,0 +1,55 @@
1
+ from abc import ABC, abstractclassmethod
2
+ from typing import Callable, Any
3
+
4
+ class ActionType:
5
+ """
6
+ 行动类型枚举 所有行动本质上为数据推送
7
+ Action Type enumeration, all actions are essentially data push
8
+
9
+ Types:
10
+ - Sim = 1, 用于表示与模拟器对接的行动
11
+ - Hub = 2, 用于表示与AppHub(前端)对接的行动
12
+ - Comp = 3, 表示综合类型 (可能同时包含与Sim以及Hub的交互)
13
+ """
14
+ Sim = 1
15
+ Hub = 2
16
+ Comp = 3
17
+ class Action:
18
+ def __init__(self, agent, type:ActionType, source: str = None, before:Callable[[list], Any] = None) -> None:
19
+ '''
20
+ 默认初始化
21
+
22
+ Args:
23
+ - agent (Agent): the related agent
24
+ - type (ActionType)
25
+ - source (str): 数据来源, 默认为None, 如果为None则会从接收用户传入的数据作为Forward函数参数, 否则从WM.Reason数据缓存中取对应数据作为参数
26
+ - before (function): 数据处理方法, 用于当Reason缓存中的参数与标准格式不符时使用
27
+ '''
28
+ self._agent = agent
29
+ self._type = type
30
+ self._source = source
31
+ self._before = before
32
+
33
+ def get_source(self):
34
+ """
35
+ 获取source数据
36
+ """
37
+ if self._source != None:
38
+ source = self._agent.Brain.Memory.Working.Reason[self._source]
39
+ if self._before != None:
40
+ source = self._before(source)
41
+ return source
42
+ else:
43
+ return None
44
+
45
+ @abstractclassmethod
46
+ async def Forward(self):
47
+ '''接口函数'''
48
+
49
+ class SimAction(Action):
50
+ def __init__(self, agent, source: str = None, before: Callable[[list], Any] = None) -> None:
51
+ super().__init__(agent, ActionType.Sim, source, before)
52
+
53
+ class HubAction(Action):
54
+ def __init__(self, agent, source: str = None, before: Callable[[list], Any] = None) -> None:
55
+ super().__init__(agent, ActionType.Hub, source, before)
@@ -0,0 +1,25 @@
1
+ from abc import ABC, abstractclassmethod
2
+ from typing import Any, Optional
3
+ from action import Action
4
+
5
+ class ActionStream:
6
+ """
7
+ 可以将多个Action聚合在一起构成一个ActionStream, Stream中的Action会顺序执行
8
+ You can collect multiple Actions into a ActionStream, actions in stream will be activated in sequence
9
+ 注意: 该部分内容目前没有使用
10
+ """
11
+ def __init__(self, actions:Optional[list[Action]]=[]) -> None:
12
+ self.actions = actions
13
+
14
+ def add_actions(self, actions:list[Action]):
15
+ """
16
+ 添加Action至当前stream
17
+
18
+ Args:
19
+ - actions (list(Action)): a list of action
20
+ """
21
+ self.actions += actions
22
+
23
+ def __call__(self) -> Any:
24
+ for action in self.actions:
25
+ action()
@@ -0,0 +1,16 @@
1
+ import time
2
+ from typing import Callable, Any
3
+
4
+ from pycityagent.ac.action import ActionType
5
+ from ..action import Action
6
+ from pycitysim.apphub import AgentMessage
7
+
8
+ class ControledAction(Action):
9
+ '''Converse行为控制器'''
10
+ def __init__(self, agent, sources: list[str] = None, before: Callable[[list], Any] = None) -> None:
11
+ super().__init__(agent, ActionType.Comp, sources, before)
12
+
13
+ async def Forward(self):
14
+ req = {'person_id': self._agent._id, 'schedules': []}
15
+ await self._agent._client.person_service.SetSchedule(req)
16
+ self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), '我已理解您的意思,正在修改我的行程', None, None)])
@@ -0,0 +1,34 @@
1
+ import time
2
+ from typing import Callable, Any
3
+
4
+ from pycityagent.ac.action import ActionType
5
+ from ..action import Action
6
+ from pycitysim.apphub import AgentMessage
7
+
8
+ class ConverseAction(Action):
9
+ '''Converse行为控制器'''
10
+ def __init__(self, agent, sources: list[str] = None, before: Callable[[list], Any] = None) -> None:
11
+ super().__init__(agent, ActionType.Comp, sources, before)
12
+
13
+ async def Forward(self):
14
+ target_agent_ids = self._agent.Brain.Memory.Working.Reason['agent_message_handle_resp'][0]
15
+ if len(target_agent_ids) == 0:
16
+ return
17
+ messages = self._agent.Brain.Memory.Working.Reason['agent_message_handle_resp'][1]
18
+ req = {'messages': []}
19
+ if len(target_agent_ids) != len(messages):
20
+ print("Warning: the number of target agent and message are not aligned, only sends matched messages")
21
+ rng = min(len(target_agent_ids), len(messages))
22
+ for i in range(rng):
23
+ dic = {}
24
+ dic['from'] = self._agent._id
25
+ dic['to'] = target_agent_ids[i]
26
+ dic['message'] = messages[i]
27
+ req['messages'].append(dic)
28
+ # * 发送至模拟器
29
+ await self._agent._client.social_service.Send(req=req)
30
+
31
+ # * 发送至AppHub
32
+ if self._agent.Hub != None and messages[0] != 'End':
33
+ # * 将信息中的第一条不同至pop
34
+ self._agent.Hub.Update(pop=messages[0])
@@ -0,0 +1,20 @@
1
+ import time
2
+ from typing import Callable, Any
3
+
4
+ from pycityagent.ac.action import ActionType
5
+ from ..action import Action
6
+ from pycitysim.apphub import AgentMessage
7
+
8
+ class IdleAction(Action):
9
+ '''idle行为控制器'''
10
+ def __init__(self, agent, sources: list[str] = None, before: Callable[[list], Any] = None) -> None:
11
+ super().__init__(agent, ActionType.Comp, sources, before)
12
+
13
+ async def Forward(self):
14
+ if len(self._agent.base['schedules']) > 0:
15
+ req = {'person_id': self._agent._id, 'schedules': []}
16
+ await self._agent._client.person_service.SetSchedule(req)
17
+ if self._agent.Hub != None:
18
+ self._agent.Hub.Update()
19
+
20
+
@@ -0,0 +1,82 @@
1
+ from typing import Callable, Any
2
+ from pycityagent.ac.action import ActionType
3
+ from ..action import Action
4
+ from pycitysim.apphub import AgentMessage
5
+ import time
6
+
7
+ def encap_msg(msg, role='user', **kwargs):
8
+ dialog = {'role': role, 'content': msg}
9
+ dialog.update(kwargs)
10
+ return dialog
11
+
12
+ class ShopAction(Action):
13
+ '''Shop行为控制器'''
14
+ def __init__(self, agent, sources: list[str] = None, before: Callable[[list], Any] = None) -> None:
15
+ super().__init__(agent, ActionType.Comp, sources, before)
16
+
17
+ async def Forward(self):
18
+ # * 与模拟器对接 - 暂时没有
19
+ # * 与AppHub对接
20
+ profile = self._agent.Image.get_profile()
21
+ self.consumption(profile)
22
+
23
+ def consumption(self, profile, mall_info):
24
+ dialogs = []
25
+ system_prompt = f'''
26
+ 你是一个在北京工作和生活的人。
27
+ {profile}
28
+ 现在是2024年1月。
29
+ 你需要为下一周的基本生活购买必需品。
30
+ '''
31
+ dialogs.append(encap_msg(system_prompt, 'system'))
32
+ actions_format = ['''{{'商品': 购买的商品的列表,'购买量': 每个商品的购买量,一个列表, '解释': '这种购买方式的原因'}}''']
33
+ actions_candidates = ['''【食品】
34
+ 米:10元/公斤
35
+ 面粉:7.5元/公斤
36
+ 新鲜蔬菜(如菠菜):7元/500克
37
+ 水果(如苹果):15元/公斤
38
+ 猪肉:30元/公斤
39
+ 鸡肉:20元/公斤
40
+ 鸡蛋:1.5元/个
41
+ 牛奶:10元/升''',
42
+ '''【清洁用品】
43
+ 洗衣液:30元/瓶
44
+ 洗洁精:20元/瓶
45
+ 垃圾袋:0.3元/个''',
46
+ '''【个人护理用品】
47
+ 牙膏:10元/支
48
+ 洗发水:30元/瓶
49
+ 沐浴露:35元/瓶
50
+ 面巾纸:5元/包''',
51
+ '''【其他】
52
+ 矿泉水:1.7元/瓶
53
+ 面包:8元/个
54
+ 辣条:3元/包''']
55
+
56
+ user_prompt = f'''
57
+ 首先确定你的消费预算。以如下格式回答,不要有冗余的文本!
58
+ {{'消费预算': 一个代表购买必需品需要消耗的钱的数量的数字}}
59
+ '''
60
+ dialogs.append(encap_msg(user_prompt))
61
+ # * 对接一:确定消费预算
62
+ self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), '我正在确定消费预算......', None, None)])
63
+ msg = self._agent._soul.text_request(dialogs)
64
+ self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), f'我的消费预算是: {msg}'), None, None])
65
+
66
+ dialogs.append(encap_msg(msg, 'assistant'))
67
+
68
+ # * 对接二:购物选择
69
+ for cand in actions_candidates:
70
+ user_prompt = f'''
71
+ 购物中心里有
72
+ {cand}
73
+ 你要买哪些商品,以如下格式回答,不要有冗余的文本!
74
+ {actions_format[0]}
75
+ '''
76
+ self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), f'我看到了\n {cand}', None, None)])
77
+ dialogs.append(encap_msg(user_prompt))
78
+ msg = self._agent._soul.text_request(dialogs)
79
+ self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), f'我的购买选择是: {msg}', None, None)])
80
+ dialogs.append(encap_msg(msg, 'assistant'))
81
+
82
+ self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), '购物完成', None, None)])
@@ -0,0 +1,41 @@
1
+ import time
2
+ from typing import Callable, Any
3
+
4
+ from pycityagent.ac.action import ActionType
5
+ from ..action import Action
6
+ from pycitysim.apphub import AgentMessage
7
+
8
+ class TripAction(Action):
9
+ '''Trip行为控制器'''
10
+ def __init__(self, agent, sources: list[str] = None, before: Callable[[list], Any] = None) -> None:
11
+ super().__init__(agent, ActionType.Comp, sources, before)
12
+
13
+ async def Forward(self):
14
+ now = self._agent.Scheduler.now
15
+ if now.is_set:
16
+ # TODO: 目前仅支持传输一张图片至前端
17
+ '''之前已经将schedule同步至模拟器了'''
18
+ if self._agent.Hub != None:
19
+ self._agent.Hub.Update(streetview=self._agent.Brain.Sence.sence_buffer['streetview'][0])
20
+ else:
21
+ '''同步schedule至模拟器'''
22
+ self._agent.Scheduler.now.is_set = True
23
+ departure_time = now.time
24
+ mode = now.mode
25
+ aoi_id = now.target_id_aoi
26
+ poi_id = now.target_id_poi
27
+ end = {'aoi_position': {'aoi_id': aoi_id, 'poi_id': poi_id}}
28
+ activity = now.description
29
+ trips = [{'mode': mode, 'end': end, 'departure_time': departure_time, 'activity': activity}]
30
+ set_schedule = [{'trips': trips, 'loop_count': 1, 'departure_time': departure_time}]
31
+
32
+ # * 与模拟器对接
33
+ req = {'person_id': self._agent._id, 'schedules': set_schedule}
34
+ await self._agent._client.person_service.SetSchedule(req)
35
+
36
+ # * 与AppHub对接
37
+ if self._agent.Hub != None:
38
+ messages = [AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), f'已到达出发时间, {activity}', None, None)]
39
+ self._agent.Hub.Update(messages)
40
+
41
+