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.
- pycityagent/__init__.py +7 -3
- pycityagent/agent.py +180 -284
- pycityagent/economy/__init__.py +5 -0
- pycityagent/economy/econ_client.py +307 -0
- pycityagent/environment/__init__.py +7 -0
- pycityagent/environment/interact/interact.py +141 -0
- pycityagent/environment/sence/__init__.py +0 -0
- pycityagent/{brain → environment/sence}/static.py +1 -1
- pycityagent/environment/sidecar/__init__.py +8 -0
- pycityagent/environment/sidecar/sidecarv2.py +109 -0
- pycityagent/environment/sim/__init__.py +29 -0
- pycityagent/environment/sim/aoi_service.py +38 -0
- pycityagent/environment/sim/client.py +126 -0
- pycityagent/environment/sim/clock_service.py +43 -0
- pycityagent/environment/sim/economy_services.py +191 -0
- pycityagent/environment/sim/lane_service.py +110 -0
- pycityagent/environment/sim/light_service.py +120 -0
- pycityagent/environment/sim/person_service.py +294 -0
- pycityagent/environment/sim/road_service.py +38 -0
- pycityagent/environment/sim/sim_env.py +145 -0
- pycityagent/environment/sim/social_service.py +58 -0
- pycityagent/environment/simulator.py +320 -0
- pycityagent/environment/utils/__init__.py +10 -0
- pycityagent/environment/utils/base64.py +16 -0
- pycityagent/environment/utils/const.py +242 -0
- pycityagent/environment/utils/geojson.py +26 -0
- pycityagent/environment/utils/grpc.py +57 -0
- pycityagent/environment/utils/map_utils.py +157 -0
- pycityagent/environment/utils/port.py +11 -0
- pycityagent/environment/utils/protobuf.py +39 -0
- pycityagent/llm/__init__.py +6 -0
- pycityagent/llm/embedding.py +136 -0
- pycityagent/llm/llm.py +430 -0
- pycityagent/llm/llmconfig.py +15 -0
- pycityagent/llm/utils.py +6 -0
- pycityagent/memory/__init__.py +11 -0
- pycityagent/memory/const.py +41 -0
- pycityagent/memory/memory.py +453 -0
- pycityagent/memory/memory_base.py +168 -0
- pycityagent/memory/profile.py +165 -0
- pycityagent/memory/self_define.py +165 -0
- pycityagent/memory/state.py +173 -0
- pycityagent/memory/utils.py +27 -0
- pycityagent/message/__init__.py +0 -0
- pycityagent/simulation/__init__.py +7 -0
- pycityagent/simulation/interview.py +36 -0
- pycityagent/simulation/simulation.py +352 -0
- pycityagent/simulation/survey/__init__.py +9 -0
- pycityagent/simulation/survey/manager.py +67 -0
- pycityagent/simulation/survey/models.py +49 -0
- pycityagent/simulation/ui/__init__.py +3 -0
- pycityagent/simulation/ui/interface.py +602 -0
- pycityagent/utils/__init__.py +0 -0
- pycityagent/utils/decorators.py +89 -0
- pycityagent/utils/parsers/__init__.py +12 -0
- pycityagent/utils/parsers/code_block_parser.py +37 -0
- pycityagent/utils/parsers/json_parser.py +86 -0
- pycityagent/utils/parsers/parser_base.py +60 -0
- pycityagent/workflow/__init__.py +24 -0
- pycityagent/workflow/block.py +164 -0
- pycityagent/workflow/prompt.py +72 -0
- pycityagent/workflow/tool.py +246 -0
- pycityagent/workflow/trigger.py +150 -0
- pycityagent-2.0.0a2.dist-info/METADATA +208 -0
- pycityagent-2.0.0a2.dist-info/RECORD +69 -0
- {pycityagent-1.0.0.dist-info → pycityagent-2.0.0a2.dist-info}/WHEEL +1 -2
- pycityagent/ac/__init__.py +0 -6
- pycityagent/ac/ac.py +0 -50
- pycityagent/ac/action.py +0 -14
- pycityagent/ac/controled.py +0 -13
- pycityagent/ac/converse.py +0 -31
- pycityagent/ac/idle.py +0 -17
- pycityagent/ac/shop.py +0 -80
- pycityagent/ac/trip.py +0 -37
- pycityagent/brain/__init__.py +0 -10
- pycityagent/brain/brain.py +0 -52
- pycityagent/brain/brainfc.py +0 -10
- pycityagent/brain/memory.py +0 -541
- pycityagent/brain/persistence/social.py +0 -1
- pycityagent/brain/persistence/spatial.py +0 -14
- pycityagent/brain/reason/shop.py +0 -37
- pycityagent/brain/reason/social.py +0 -148
- pycityagent/brain/reason/trip.py +0 -67
- pycityagent/brain/reason/user.py +0 -122
- pycityagent/brain/retrive/social.py +0 -6
- pycityagent/brain/scheduler.py +0 -408
- pycityagent/brain/sence.py +0 -375
- pycityagent/cc/__init__.py +0 -5
- pycityagent/cc/cc.py +0 -102
- pycityagent/cc/conve.py +0 -6
- pycityagent/cc/idle.py +0 -20
- pycityagent/cc/shop.py +0 -6
- pycityagent/cc/trip.py +0 -13
- pycityagent/cc/user.py +0 -13
- pycityagent/hubconnector/__init__.py +0 -3
- pycityagent/hubconnector/hubconnector.py +0 -137
- pycityagent/image/__init__.py +0 -3
- pycityagent/image/image.py +0 -158
- pycityagent/simulator.py +0 -161
- pycityagent/st/__init__.py +0 -4
- pycityagent/st/st.py +0 -96
- pycityagent/urbanllm/__init__.py +0 -3
- pycityagent/urbanllm/urbanllm.py +0 -132
- pycityagent-1.0.0.dist-info/LICENSE +0 -21
- pycityagent-1.0.0.dist-info/METADATA +0 -181
- pycityagent-1.0.0.dist-info/RECORD +0 -48
- pycityagent-1.0.0.dist-info/top_level.txt +0 -1
- /pycityagent/{brain/persistence/__init__.py → config.py} +0 -0
- /pycityagent/{brain/reason → environment/interact}/__init__.py +0 -0
- /pycityagent/{brain/retrive → environment/message}/__init__.py +0 -0
@@ -0,0 +1,150 @@
|
|
1
|
+
import asyncio
|
2
|
+
from typing import Any, Callable, Dict, List, Optional, Union, Type
|
3
|
+
import socket
|
4
|
+
from ..memory import Memory
|
5
|
+
from ..environment import Simulator
|
6
|
+
|
7
|
+
KEY_TRIGGER_COMPONENTS = [Memory, Simulator]
|
8
|
+
|
9
|
+
class EventTrigger:
|
10
|
+
"""Base class for event triggers that wait for specific conditions to be met."""
|
11
|
+
# 定义该trigger需要的组件类型
|
12
|
+
required_components: List[Type] = []
|
13
|
+
|
14
|
+
def __init__(self, block=None):
|
15
|
+
self.block = block
|
16
|
+
if block is not None:
|
17
|
+
self.initialize()
|
18
|
+
|
19
|
+
def initialize(self) -> None:
|
20
|
+
"""Initialize the trigger with necessary dependencies."""
|
21
|
+
if not self.block:
|
22
|
+
raise RuntimeError("Block not set for trigger")
|
23
|
+
|
24
|
+
# 检查所需组件是否都存在
|
25
|
+
missing_components = []
|
26
|
+
for component_type in self.required_components:
|
27
|
+
component_name = component_type.__name__.lower()
|
28
|
+
if not hasattr(self.block, component_name):
|
29
|
+
missing_components.append(component_type.__name__)
|
30
|
+
|
31
|
+
if missing_components:
|
32
|
+
raise RuntimeError(
|
33
|
+
f"Block is missing required components for {self.__class__.__name__}: "
|
34
|
+
f"{', '.join(missing_components)}"
|
35
|
+
)
|
36
|
+
|
37
|
+
async def wait_for_trigger(self) -> None:
|
38
|
+
"""Wait for the event trigger to be activated.
|
39
|
+
|
40
|
+
Raises:
|
41
|
+
NotImplementedError: Subclasses must implement this method.
|
42
|
+
"""
|
43
|
+
raise NotImplementedError
|
44
|
+
|
45
|
+
class MemoryChangeTrigger(EventTrigger):
|
46
|
+
"""Event trigger that activates when a specific key in memory changes."""
|
47
|
+
required_components = [Memory]
|
48
|
+
|
49
|
+
def __init__(self, key: str) -> None:
|
50
|
+
"""Initialize the memory change trigger.
|
51
|
+
|
52
|
+
Args:
|
53
|
+
key (str): The key in memory to monitor for changes.
|
54
|
+
"""
|
55
|
+
self.key = key
|
56
|
+
self.trigger_event = asyncio.Event()
|
57
|
+
self._initialized = False
|
58
|
+
super().__init__()
|
59
|
+
|
60
|
+
def initialize(self) -> None:
|
61
|
+
"""Initialize the trigger with memory from block."""
|
62
|
+
super().initialize() # 首先检查必需组件
|
63
|
+
self.memory = self.block.memory
|
64
|
+
asyncio.create_task(self.memory.add_watcher(self.key, self.trigger_event.set))
|
65
|
+
self._initialized = True
|
66
|
+
|
67
|
+
async def wait_for_trigger(self) -> None:
|
68
|
+
"""Wait for the memory change trigger to be activated."""
|
69
|
+
if not self._initialized:
|
70
|
+
raise RuntimeError("Trigger not properly initialized")
|
71
|
+
await self.trigger_event.wait()
|
72
|
+
self.trigger_event.clear()
|
73
|
+
|
74
|
+
|
75
|
+
class TimeTrigger(EventTrigger):
|
76
|
+
"""Event trigger that activates periodically based on time intervals."""
|
77
|
+
required_components = [Simulator]
|
78
|
+
|
79
|
+
def __init__(self,
|
80
|
+
days: Optional[int] = None,
|
81
|
+
hours: Optional[int] = None,
|
82
|
+
minutes: Optional[int] = None) -> None:
|
83
|
+
"""Initialize the time trigger with interval settings.
|
84
|
+
|
85
|
+
Args:
|
86
|
+
days (Optional[int]): Execute every N days
|
87
|
+
hours (Optional[int]): Execute every N hours
|
88
|
+
minutes (Optional[int]): Execute every N minutes
|
89
|
+
|
90
|
+
Raises:
|
91
|
+
ValueError: If all interval parameters are None or negative
|
92
|
+
"""
|
93
|
+
if all(param is None for param in (days, hours, minutes)):
|
94
|
+
raise ValueError("At least one time interval must be specified")
|
95
|
+
|
96
|
+
# 验证参数有效性
|
97
|
+
for param_name, param_value in [('days', days), ('hours', hours), ('minutes', minutes)]:
|
98
|
+
if param_value is not None and param_value < 0:
|
99
|
+
raise ValueError(f"{param_name} cannot be negative")
|
100
|
+
|
101
|
+
# 将所有时间间隔转换为秒
|
102
|
+
self.interval = 0
|
103
|
+
if days is not None:
|
104
|
+
self.interval += days * 24 * 60 * 60
|
105
|
+
if hours is not None:
|
106
|
+
self.interval += hours * 60 * 60
|
107
|
+
if minutes is not None:
|
108
|
+
self.interval += minutes * 60
|
109
|
+
|
110
|
+
self.trigger_event = asyncio.Event()
|
111
|
+
self._initialized = False
|
112
|
+
self._monitoring_task = None
|
113
|
+
self._last_trigger_time = None
|
114
|
+
super().__init__()
|
115
|
+
|
116
|
+
def initialize(self) -> None:
|
117
|
+
"""Initialize the trigger with necessary dependencies."""
|
118
|
+
super().initialize() # 首先检查必需组件
|
119
|
+
self.memory = self.block.memory
|
120
|
+
self.simulator = self.block.simulator
|
121
|
+
# 启动时间监控任务
|
122
|
+
self._monitoring_task = asyncio.create_task(self._monitor_time())
|
123
|
+
self._initialized = True
|
124
|
+
|
125
|
+
async def _monitor_time(self):
|
126
|
+
"""持续监控时间并在达到间隔时触发事件"""
|
127
|
+
# 第一次调用时直接触发
|
128
|
+
self.trigger_event.set()
|
129
|
+
|
130
|
+
while True:
|
131
|
+
try:
|
132
|
+
current_time = await self.simulator.GetTime()
|
133
|
+
|
134
|
+
# 如果是第一次或者已经过了指定的时间间隔
|
135
|
+
if (self._last_trigger_time is None or
|
136
|
+
current_time - self._last_trigger_time >= self.interval):
|
137
|
+
self._last_trigger_time = current_time
|
138
|
+
self.trigger_event.set()
|
139
|
+
|
140
|
+
await asyncio.sleep(5) # 避免过于频繁的检查
|
141
|
+
except Exception as e:
|
142
|
+
print(f"Error in time monitoring: {e}")
|
143
|
+
await asyncio.sleep(10) # 发生错误时等待较长时间
|
144
|
+
|
145
|
+
async def wait_for_trigger(self) -> None:
|
146
|
+
"""Wait for the time trigger to be activated."""
|
147
|
+
if not self._initialized:
|
148
|
+
raise RuntimeError("Trigger not properly initialized")
|
149
|
+
await self.trigger_event.wait()
|
150
|
+
self.trigger_event.clear()
|
@@ -0,0 +1,208 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: pycityagent
|
3
|
+
Version: 2.0.0a2
|
4
|
+
Summary: LLM-based城市环境agent构建库
|
5
|
+
License: MIT
|
6
|
+
Author: Yuwei Yan
|
7
|
+
Author-email: pinkgranite86@gmail.com
|
8
|
+
Requires-Python: >=3.10,<4.0
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
10
|
+
Classifier: Operating System :: OS Independent
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
16
|
+
Requires-Dist: Pillow (==11.0.0)
|
17
|
+
Requires-Dist: Requests (==2.32.3)
|
18
|
+
Requires-Dist: Shapely (==2.0.6)
|
19
|
+
Requires-Dist: aiohttp (==3.10.10)
|
20
|
+
Requires-Dist: citystreetview (==1.2.4)
|
21
|
+
Requires-Dist: dashscope (==1.14.1)
|
22
|
+
Requires-Dist: geojson (==3.1.0)
|
23
|
+
Requires-Dist: gradio (>=5.7.1,<6.0.0)
|
24
|
+
Requires-Dist: grpcio (==1.67.1)
|
25
|
+
Requires-Dist: matplotlib (==3.8.3)
|
26
|
+
Requires-Dist: mosstool (==1.0.24)
|
27
|
+
Requires-Dist: networkx (==3.2.1)
|
28
|
+
Requires-Dist: numpy (>=1.20.0,<2.0.0)
|
29
|
+
Requires-Dist: openai (==1.54.3)
|
30
|
+
Requires-Dist: poetry (>=1.2.2)
|
31
|
+
Requires-Dist: protobuf (<=4.24.0)
|
32
|
+
Requires-Dist: pycitydata (==1.0.0)
|
33
|
+
Requires-Dist: pycityproto (==2.0.7)
|
34
|
+
Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
|
35
|
+
Requires-Dist: sidecar (==0.7.0)
|
36
|
+
Requires-Dist: zhipuai (>=2.1.5.20230904,<3.0.0.0)
|
37
|
+
Description-Content-Type: text/markdown
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
<div style="text-align: center; background-color: white; padding: 20px; border-radius: 30px;">
|
42
|
+
<img src="./static/cityagent_logo.png" alt="CityAgent Logo" width="200" style="display: block; margin: 0 auto;">
|
43
|
+
<h1 style="color: black; margin: 0; font-size: 3em;">CityAgent: LLM Agents in City</h1>
|
44
|
+
</div>
|
45
|
+
|
46
|
+
|
47
|
+
# 🚀 CityAgent
|
48
|
+
  
|
49
|
+
[](https://docs.fiblab.net/pycityagent)  
|
50
|
+
|
51
|
+
|
52
|
+
CityAgent is an advanced framework specifically designed for building intelligent agents in urban simulation environments. With CityAgent, you can easily create and manage agents, enabling complex urban scenarios to be modeled and simulated efficiently.
|
53
|
+
|
54
|
+
## 🌟 Features
|
55
|
+
- **Modular Design**: Plug-and-play components for agent behavior.
|
56
|
+
- **Urban Environment Simulation**: Built to simulate diverse urban scenarios.
|
57
|
+
- **LLM Integration**: Connects to language models for enriched agent behavior.
|
58
|
+
- **Flexible Configuration**: YAML-based configuration for easy customization.
|
59
|
+
|
60
|
+
## 📑 Table of Contents
|
61
|
+
|
62
|
+
1. [News](#news)
|
63
|
+
2. [Framework](#framework)
|
64
|
+
3. [Setup](#setup)
|
65
|
+
4. [QuickStart](#quickstart)
|
66
|
+
5. [Contributing](#contributing)
|
67
|
+
6. [License](#license)
|
68
|
+
|
69
|
+
<a id="news"></a>
|
70
|
+
## 📰 News
|
71
|
+
|
72
|
+
- 📢 **11.10** - Initial update is now live!
|
73
|
+
- 📢 **2.x version is not compatible* with 1.x version**
|
74
|
+
|
75
|
+
Stay tuned for upcoming updates!
|
76
|
+
|
77
|
+
<a id="framework"></a>
|
78
|
+
## 🛠️ Framework
|
79
|
+
|
80
|
+
CityAgent is built with a multi-layered architecture that allows users to create and manage intelligent agents for urban environments in a scalable and flexible manner. The framework is divided into several key layers, each responsible for different functionalities as depicted in the diagram below:
|
81
|
+
|
82
|
+
<img src="./static/framework.png" alt="CityAgent Framework Overview" width="600" style="display: block; margin: 20px auto;">
|
83
|
+
|
84
|
+
### Architectural Layers
|
85
|
+
- **Model Layer**: Handles agent configuration, task definitions, logging setup, and result aggregation.
|
86
|
+
- **Task Configuration**: Defines agent behaviors and objectives.
|
87
|
+
- **Unified Execution**: Centralized entry point for agent processes.
|
88
|
+
|
89
|
+
- **Agent Layer**: Implements multi-head workflows to manage agent actions.
|
90
|
+
- **Memory**: Stores agent-related information, such as location and motion.
|
91
|
+
- **Static Profiles**: Maintains unchanging agent attributes.
|
92
|
+
- **Custom Data Pool**: Functions as a working memory.
|
93
|
+
- **Multi-Head Workflow**: Supports both normal and event-driven modes.
|
94
|
+
- **Reason Block**: Utilizes LLMs to determine decisions based on context and tools.
|
95
|
+
- **Route Block**: Chooses the best path based on defined criteria using LLMs or rules.
|
96
|
+
- **Action Block**: Executes actions as per defined contexts and tools.
|
97
|
+
|
98
|
+
- **Message Layer**: Facilitates agent communication through peer-to-peer (P2P), peer-to-group (P2G), and group chats.
|
99
|
+
|
100
|
+
- **Environment Layer**: Manages interaction with the urban environment.
|
101
|
+
- **Environment Sensing**: Reads data from the environment.
|
102
|
+
- **Interaction Handling**: Writes or modifies environmental states.
|
103
|
+
- **Message Management**: Handles incoming and outgoing agent messages.
|
104
|
+
|
105
|
+
- **LLM Layer**: Provides configuration and integration for using LLMs in the agent's workflow.
|
106
|
+
- **Prompting & Execution**: Supports model invocation and monitoring.
|
107
|
+
- **Model Support**: Compatible with various LLMs, such as OpenAI, Qwen, Deepseek, etc.
|
108
|
+
|
109
|
+
- **Tool Layer**: Provides additional utilities to the agents.
|
110
|
+
- **String Processing**: Handles parsing and formatting.
|
111
|
+
- **Result Analysis**: Parses responses in formats like JSON or dictionaries.
|
112
|
+
- **Data Storage & Retrieval**: Includes ranking and search tools.
|
113
|
+
|
114
|
+
<a id="setup"></a>
|
115
|
+
## ⚙️ Setup
|
116
|
+
|
117
|
+
You can set up CityAgent in two different ways:
|
118
|
+
|
119
|
+
### 1. From Scratch
|
120
|
+
|
121
|
+
Follow these steps to set up CityAgent from scratch by cloning the repository. The project is built using Python and managed with Poetry.
|
122
|
+
|
123
|
+
1. **Clone the Repository**
|
124
|
+
```bash
|
125
|
+
git clone [This Repository]
|
126
|
+
```
|
127
|
+
2. **Navigate to the Project Directory**
|
128
|
+
```bash
|
129
|
+
cd pycityagent
|
130
|
+
```
|
131
|
+
3. **Install Poetry** (if not installed)
|
132
|
+
```bash
|
133
|
+
curl -sSL https://install.python-poetry.org | python3 -
|
134
|
+
```
|
135
|
+
4. **Install Dependencies**
|
136
|
+
```bash
|
137
|
+
poetry install
|
138
|
+
```
|
139
|
+
5. **Activate the Virtual Environment**
|
140
|
+
```bash
|
141
|
+
poetry shell
|
142
|
+
```
|
143
|
+
|
144
|
+
### 2. Install via pip
|
145
|
+
|
146
|
+
This method is not yet available. Stay tuned for future updates!
|
147
|
+
|
148
|
+
<a id="quickstart"></a>
|
149
|
+
## 🚀 QuickStart
|
150
|
+
|
151
|
+
Get started with CityAgent in just a few minutes!
|
152
|
+
|
153
|
+
### 1. Config Configuration
|
154
|
+
CityAgent uses a configuration file written in `.yaml` format to manage settings for various components. Below is a sample configuration file (`config_template.yaml`) that showcases the structure:
|
155
|
+
|
156
|
+
```yaml
|
157
|
+
llm_request:
|
158
|
+
text_request:
|
159
|
+
request_type: openai
|
160
|
+
api_key: <YOUR_API_KEY>
|
161
|
+
model: gpt-4o
|
162
|
+
img_understand_request:
|
163
|
+
request_type: none
|
164
|
+
api_key: none
|
165
|
+
model: none
|
166
|
+
img_generate_request:
|
167
|
+
request_type: none
|
168
|
+
api_key: none
|
169
|
+
model: none
|
170
|
+
|
171
|
+
simulator_request:
|
172
|
+
simulator:
|
173
|
+
server: https://api-opencity-2x.fiblab.net:58081
|
174
|
+
map_request:
|
175
|
+
mongo_uri: <MONGO_URI>
|
176
|
+
mongo_db: llmsim
|
177
|
+
mongo_coll: map_beijing5ring_withpoi_0424
|
178
|
+
cache_dir: ./cache
|
179
|
+
route_request:
|
180
|
+
server: http://api-opencity-2x.fiblab.net:58082
|
181
|
+
streetview_request:
|
182
|
+
engine: baidumap / googlemap
|
183
|
+
mapAK: baidumap api-key (if you use baidumap engine)
|
184
|
+
proxy: googlemap proxy (if you use googlemap engine)
|
185
|
+
```
|
186
|
+
|
187
|
+
### 2. Example Usage
|
188
|
+
To get started quickly, please refer to the `examples` folder in the repository. It contains sample scripts and configurations to help you understand how to create and use agents in an urban simulation environment.
|
189
|
+
|
190
|
+
<a id="contributing"></a>
|
191
|
+
## 🤝 Contributing
|
192
|
+
We welcome contributions from the community!.
|
193
|
+
|
194
|
+
<a id="license"></a>
|
195
|
+
## 📄 License
|
196
|
+
|
197
|
+
CityAgent is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
|
198
|
+
|
199
|
+
---
|
200
|
+
|
201
|
+
Feel free to reach out if you have any questions, suggestions, or want to collaborate!
|
202
|
+
|
203
|
+
---
|
204
|
+
|
205
|
+
> **Follow us**: Stay updated with the latest news and features by watching the repository.
|
206
|
+
|
207
|
+
---
|
208
|
+
|
@@ -0,0 +1,69 @@
|
|
1
|
+
pycityagent/__init__.py,sha256=n56bWkAUEcvjDsb7LcJpaGjlrriSKPnR0yBhwRfEYBA,212
|
2
|
+
pycityagent/agent.py,sha256=QzVBgTdlwZEY0pQQB9nTruWiIc3t8mZxLzv5cId1IbY,5951
|
3
|
+
pycityagent/config.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
pycityagent/economy/__init__.py,sha256=aonY4WHnx-6EGJ4WKrx4S-2jAkYNLtqUA04jp6q8B7w,75
|
5
|
+
pycityagent/economy/econ_client.py,sha256=qQb_kZneEXGBRaS_y5Jdoi95I8GyjKEsDSC4s6V6R7w,10829
|
6
|
+
pycityagent/environment/__init__.py,sha256=awHxlOud-btWbk0FCS4RmGJ13W84oVCkbGfcrhKqihA,240
|
7
|
+
pycityagent/environment/interact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
|
+
pycityagent/environment/interact/interact.py,sha256=LNl_HlasoW5H72GiBnbQkCP51qDIp5dpk-EShA7RPWk,5946
|
9
|
+
pycityagent/environment/message/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
|
+
pycityagent/environment/sence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
11
|
+
pycityagent/environment/sence/static.py,sha256=fdBjHKacNiDCKhvQkc9WgEYYSO0peMC5lb8CcXl9iNc,29101
|
12
|
+
pycityagent/environment/sidecar/__init__.py,sha256=RFbOf40aYBP4WwRpFkua5tlRE_OtMcMNyp1Lew_aaAU,235
|
13
|
+
pycityagent/environment/sidecar/sidecarv2.py,sha256=beKlYZgt38EQbV1x6NWQo7xVXyB-5QHfbwJexyXu7Tg,3252
|
14
|
+
pycityagent/environment/sim/__init__.py,sha256=JVG6sSD2Hbohl1TtKjuQi7_M7tKMrFh9vl3QV3VA5O0,724
|
15
|
+
pycityagent/environment/sim/aoi_service.py,sha256=pYSsqdGBpfQvp0-umNJir_7Yph75OJqhLjFQ2QWhSP8,1211
|
16
|
+
pycityagent/environment/sim/client.py,sha256=MHR7Hhu-Cr7B61d3K_QDpSJh4HrUU9JQf6Cu7_8pdsE,3493
|
17
|
+
pycityagent/environment/sim/clock_service.py,sha256=YG_A_IA7iJp9rOQE3bCPgppzuzzUwWMCzlxSUdOy088,1326
|
18
|
+
pycityagent/environment/sim/economy_services.py,sha256=_WirbF-vv4U1VK5oACiEC3Bse9Pia9HWNEw21suEnAs,7093
|
19
|
+
pycityagent/environment/sim/lane_service.py,sha256=6ljWiX_GbZd-a-fEcktDZncxBkraLA2LDE_pVV99uLs,3896
|
20
|
+
pycityagent/environment/sim/light_service.py,sha256=ezYGcV_PkZ6I-yv48LNEjsytwwwQx-1Qp2QCWXWIhdQ,4215
|
21
|
+
pycityagent/environment/sim/person_service.py,sha256=nIvOsoBoqOTDYtsiThg07-4ZBgkTUDEbb3dHyOjzyb8,10652
|
22
|
+
pycityagent/environment/sim/road_service.py,sha256=Pab182YRcrjLw3UcfoD1Hdd6O8XEdi6Q2hJKzFcpSWE,1272
|
23
|
+
pycityagent/environment/sim/sim_env.py,sha256=HI1LcS_FotDKQ6vBnx0e49prXSABOfA20aU9KM-ZkCY,4625
|
24
|
+
pycityagent/environment/sim/social_service.py,sha256=a9mGZm95EFUIKQJUwQi9f8anmtf2SK4XqGfE2W9IXSQ,2001
|
25
|
+
pycityagent/environment/simulator.py,sha256=lw6-T6HFeE6lOtbTQdKZLre2cX7PZkXftRt7wC4mE-8,11858
|
26
|
+
pycityagent/environment/utils/__init__.py,sha256=PUx8etr2p_AA7F50ZR7g27odkgv-nOqFZa61ER8-DLg,221
|
27
|
+
pycityagent/environment/utils/base64.py,sha256=hoREzQo3FXMN79pqQLO2jgsDEvudciomyKii7MWljAM,374
|
28
|
+
pycityagent/environment/utils/const.py,sha256=3RMNy7_bE7-23K90j9DFW_tWEzu8s7hSTgKbV-3BFl4,5327
|
29
|
+
pycityagent/environment/utils/geojson.py,sha256=Ieg8Bzw63kKhJlhDIOVDoh-wQO4Sbtoe47FtIOy5wWg,686
|
30
|
+
pycityagent/environment/utils/grpc.py,sha256=6EJwKXXktIWb1NcUiJzIRmfrY0S03QAXXGcCDHqAT00,1998
|
31
|
+
pycityagent/environment/utils/map_utils.py,sha256=oqrRgQICC3SYw6gwjjPe_MAif7_t6dlrQpY8E32Fexs,5777
|
32
|
+
pycityagent/environment/utils/port.py,sha256=3OM6kSUt3PxvDUOlgyiendBtETaWU8Mzk_8H0TzTmYg,295
|
33
|
+
pycityagent/environment/utils/protobuf.py,sha256=0jBvK_s96y_n7tuMbG22TOtQmg71SGV4ONDy2IGsU9o,1148
|
34
|
+
pycityagent/llm/__init__.py,sha256=0-_q-StY0g4p9mdUNve_kqzHNXwVxedNsvxGXSQYq6o,144
|
35
|
+
pycityagent/llm/embedding.py,sha256=vtjMUuInrtn0WRPXp3cmYEhwHXJ0q6zszdXsjTsgNeQ,4499
|
36
|
+
pycityagent/llm/llm.py,sha256=PFbGCVQOLNJEfd5KaZdXABYIoPTFOGrNXIAE2eDRCP4,19191
|
37
|
+
pycityagent/llm/llmconfig.py,sha256=WcyyfjP6XVLCDj2aemEM6ogQCWNxbTXQBiR0WjN4E8E,457
|
38
|
+
pycityagent/llm/utils.py,sha256=emio-WhYh6vYb5Sp7KsnW9hKKe_jStjJsGBBJfcAPgM,153
|
39
|
+
pycityagent/memory/__init__.py,sha256=Hs2NhYpIG-lvpwPWwj4DydB1sxtjz7cuA4iDAzCXnjI,243
|
40
|
+
pycityagent/memory/const.py,sha256=zsyz282_8gH7MiFwBlnfN8RUh7Z_JcbP7H_dtJDmnK8,888
|
41
|
+
pycityagent/memory/memory.py,sha256=I5GJ77eQZBcKcWevZQcHUBTd2XNT4CotE6mmvB5mA8I,18170
|
42
|
+
pycityagent/memory/memory_base.py,sha256=U6odnR_5teaT3N2XF0W2McCxPyxtCpw61DjRVIO6p6I,5639
|
43
|
+
pycityagent/memory/profile.py,sha256=dJPeZ91DZcYdR7zmsfSSQx7epvvE1mrvj4-4WAT0tkM,5217
|
44
|
+
pycityagent/memory/self_define.py,sha256=vH2PrRSIykAOc5FebKN2JFQdx17nfR-IWv4s_ZS0YJk,5214
|
45
|
+
pycityagent/memory/state.py,sha256=xqOxo69sZX1M9eCUMbg5BUlSFe9LdMDH3oTWDXC0y64,5148
|
46
|
+
pycityagent/memory/utils.py,sha256=97lkenn-36wgt7uWb3Z39BXdJ5zlEQTQnQBFpoND1gg,879
|
47
|
+
pycityagent/message/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
|
+
pycityagent/simulation/__init__.py,sha256=SZQzjcGR-zkTDrE81bQuEdKn7yjk4BcZ9m7o1wTc7EE,111
|
49
|
+
pycityagent/simulation/interview.py,sha256=mY4Vpz0vgJo4rrMy3TZnwwM-iVDL6J0LgjOxbEuV27E,1173
|
50
|
+
pycityagent/simulation/simulation.py,sha256=XiUlW9zmnvf4RRkDI6HghmueeOfIpkIKuTBzp9z6uB0,12669
|
51
|
+
pycityagent/simulation/survey/__init__.py,sha256=hFJ0Q1yo4jwKAIXP17sznBSWwm2Lyh3F3W3Lly40wr8,172
|
52
|
+
pycityagent/simulation/survey/manager.py,sha256=DkNrb12Ay7TiGURoyJTFFeUdV1zh6TgRpTmpZOblADw,2158
|
53
|
+
pycityagent/simulation/survey/models.py,sha256=-3EKe-qvkUJ2TH24ow0A_Lc4teGet7pueN2T5mOR_Qc,1308
|
54
|
+
pycityagent/simulation/ui/__init__.py,sha256=4aevYl09KSku2NEpFZhyFNxI1qlswbrAFwhF_YhxFTo,62
|
55
|
+
pycityagent/simulation/ui/interface.py,sha256=cSQRQhuA5Gj-X7anuN9tmRpG6-I8QYOuswjIWUeSvio,21636
|
56
|
+
pycityagent/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
57
|
+
pycityagent/utils/decorators.py,sha256=v21QD_cKMTQ-t1UorXjgbWDFzeRehvprDalhQHIQxgg,3160
|
58
|
+
pycityagent/utils/parsers/__init__.py,sha256=p5RZ4azJIpMgmKIU2evIp2moNzFabIR9X1LVNjT6Fq4,279
|
59
|
+
pycityagent/utils/parsers/code_block_parser.py,sha256=Cs2Z_hm9VfNCpPPll1TwteaJF-HAQPs-3RApsOekFm4,1173
|
60
|
+
pycityagent/utils/parsers/json_parser.py,sha256=FZ3XN1g8z4Dr2TFraUOoah1oQcze4fPd2m01hHoX0Mo,2917
|
61
|
+
pycityagent/utils/parsers/parser_base.py,sha256=k6DVqwAMK3jJdOP4IeLE-aFPm3V2F-St5qRBuRdx4aU,1742
|
62
|
+
pycityagent/workflow/__init__.py,sha256=EyCcjB6LyBim-5iAOPe4m2qfvghEPqu1ZdGfy4KPeZ8,551
|
63
|
+
pycityagent/workflow/block.py,sha256=IXfarqIax6yVP_DniU6ZsPTT8QA4aIDnvZbwP_MtRaw,6054
|
64
|
+
pycityagent/workflow/prompt.py,sha256=cmzKEmlzjdwg50uwfnTnN_6xNJA8OVjo5fdmcsaTbdU,2886
|
65
|
+
pycityagent/workflow/tool.py,sha256=4sYbH-OVNffXbK3m58f8ap6WrS_uMzhK1c_Rl2er1B0,8981
|
66
|
+
pycityagent/workflow/trigger.py,sha256=u2aPBOzTWvdYKb45nUsQfA_uRunsmbLzB7ztSU2mlrQ,5736
|
67
|
+
pycityagent-2.0.0a2.dist-info/METADATA,sha256=IrHbMpcjWubG-yxzVCPB50qjlaeQXq2UYxyksRd3P6U,7537
|
68
|
+
pycityagent-2.0.0a2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
69
|
+
pycityagent-2.0.0a2.dist-info/RECORD,,
|
pycityagent/ac/__init__.py
DELETED
pycityagent/ac/ac.py
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
from typing import Any
|
2
|
-
from .trip import TripAction
|
3
|
-
from .shop import ShopAction
|
4
|
-
from .converse import ConverseAction
|
5
|
-
from .controled import ControledAction
|
6
|
-
from .idle import IdleAction
|
7
|
-
|
8
|
-
class ActionController:
|
9
|
-
"""
|
10
|
-
Agent行为控制器: 与AppHub(simulator)对接
|
11
|
-
Agent Controller: Connect with AppHub and Simulator
|
12
|
-
Note: Actions are predefined. By now, user defined actions are not supported
|
13
|
-
"""
|
14
|
-
def __init__(self, agent, config=None) -> None:
|
15
|
-
self._agent = agent
|
16
|
-
self._trip = TripAction(agent)
|
17
|
-
self._shop = ShopAction(agent)
|
18
|
-
self._converse = ConverseAction(agent)
|
19
|
-
self._control = ControledAction(agent)
|
20
|
-
self._idle = IdleAction(agent)
|
21
|
-
self._config = config
|
22
|
-
|
23
|
-
async def Run(self):
|
24
|
-
# TODO: 后期补充相关扩展接口,应该根据state-action关联模块进行(为了方便用户定义更加丰富的状态)
|
25
|
-
if self._agent.state == 'idle':
|
26
|
-
await self._idle()
|
27
|
-
elif self._agent.state == 'trip':
|
28
|
-
await self._trip()
|
29
|
-
elif self._agent.state == 'conve':
|
30
|
-
await self._converse()
|
31
|
-
elif self._agent.state == 'shop':
|
32
|
-
await self._shop()
|
33
|
-
elif self._agent.state == 'controled':
|
34
|
-
await self._control()
|
35
|
-
|
36
|
-
@property
|
37
|
-
def TripAction(self):
|
38
|
-
return self._trip
|
39
|
-
|
40
|
-
@property
|
41
|
-
def ShopAction(self):
|
42
|
-
return self._shop
|
43
|
-
|
44
|
-
@property
|
45
|
-
def ConveAction(self):
|
46
|
-
return self._converse
|
47
|
-
|
48
|
-
@property
|
49
|
-
def ControlAction(self):
|
50
|
-
return self._controls
|
pycityagent/ac/action.py
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
from abc import ABC, abstractclassmethod
|
2
|
-
from typing import Any
|
3
|
-
|
4
|
-
class Action:
|
5
|
-
def __init__(self, agent) -> None:
|
6
|
-
'''默认初始化'''
|
7
|
-
self._agent = agent
|
8
|
-
|
9
|
-
@abstractclassmethod
|
10
|
-
async def Forward(self):
|
11
|
-
'''接口函数'''
|
12
|
-
|
13
|
-
async def __call__(self) -> Any:
|
14
|
-
await self.Forward()
|
pycityagent/ac/controled.py
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
import time
|
2
|
-
from .action import Action
|
3
|
-
from pycitysim.apphub import AgentMessage
|
4
|
-
|
5
|
-
class ControledAction(Action):
|
6
|
-
'''Converse行为控制器'''
|
7
|
-
def __init__(self, agent) -> None:
|
8
|
-
super().__init__(agent)
|
9
|
-
|
10
|
-
async def Forward(self):
|
11
|
-
req = {'person_id': self._agent._id, 'schedules': []}
|
12
|
-
await self._agent._client.person_service.SetSchedule(req)
|
13
|
-
self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), '我已理解您的意思,正在修改我的行程', None, None)])
|
pycityagent/ac/converse.py
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
import time
|
2
|
-
from .action import Action
|
3
|
-
from pycitysim.apphub import AgentMessage
|
4
|
-
|
5
|
-
class ConverseAction(Action):
|
6
|
-
'''Converse行为控制器'''
|
7
|
-
def __init__(self, agent) -> None:
|
8
|
-
super().__init__(agent)
|
9
|
-
|
10
|
-
async def Forward(self):
|
11
|
-
target_agent_ids = self._agent.Brain.Memory.Working.Reason['agent_message_handle_resp'][0]
|
12
|
-
if len(target_agent_ids) == 0:
|
13
|
-
return
|
14
|
-
messages = self._agent.Brain.Memory.Working.Reason['agent_message_handle_resp'][1]
|
15
|
-
req = {'messages': []}
|
16
|
-
if len(target_agent_ids) != len(messages):
|
17
|
-
print("Warning: the number of target agent and message are not aligned, only sends matched messages")
|
18
|
-
rng = min(len(target_agent_ids), len(messages))
|
19
|
-
for i in range(rng):
|
20
|
-
dic = {}
|
21
|
-
dic['from'] = self._agent._id
|
22
|
-
dic['to'] = target_agent_ids[i]
|
23
|
-
dic['message'] = messages[i]
|
24
|
-
req['messages'].append(dic)
|
25
|
-
# * 发送至模拟器
|
26
|
-
await self._agent._client.social_service.Send(req=req)
|
27
|
-
|
28
|
-
# * 发送至AppHub
|
29
|
-
if self._agent.Hub != None and messages[0] != 'End':
|
30
|
-
# * 将信息中的第一条不同至pop
|
31
|
-
self._agent.Hub.Update(pop=messages[0])
|
pycityagent/ac/idle.py
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
import time
|
2
|
-
from .action import Action
|
3
|
-
from pycitysim.apphub import AgentMessage
|
4
|
-
|
5
|
-
class IdleAction(Action):
|
6
|
-
'''idle行为控制器'''
|
7
|
-
def __init__(self, agent) -> None:
|
8
|
-
super().__init__(agent)
|
9
|
-
|
10
|
-
async def Forward(self):
|
11
|
-
if len(self._agent.base['schedules']) > 0:
|
12
|
-
req = {'person_id': self._agent._id, 'schedules': []}
|
13
|
-
await self._agent._client.person_service.SetSchedule(req)
|
14
|
-
if self._agent.Hub != None:
|
15
|
-
self._agent.Hub.Update()
|
16
|
-
|
17
|
-
|
pycityagent/ac/shop.py
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
from .action import Action
|
2
|
-
from pycitysim.apphub import AgentMessage
|
3
|
-
import time
|
4
|
-
|
5
|
-
def encap_msg(msg, role='user', **kwargs):
|
6
|
-
dialog = {'role': role, 'content': msg}
|
7
|
-
dialog.update(kwargs)
|
8
|
-
return dialog
|
9
|
-
|
10
|
-
class ShopAction(Action):
|
11
|
-
'''Shop行为控制器'''
|
12
|
-
def __init__(self, agent) -> None:
|
13
|
-
super().__init__(agent)
|
14
|
-
|
15
|
-
async def Forward(self):
|
16
|
-
# * 与模拟器对接 - 暂时没有
|
17
|
-
# * 与AppHub对接
|
18
|
-
profile = self._agent.Image.get_profile()
|
19
|
-
self.consumption(profile)
|
20
|
-
|
21
|
-
def consumption(self, profile, mall_info):
|
22
|
-
dialogs = []
|
23
|
-
system_prompt = f'''
|
24
|
-
你是一个在北京工作和生活的人。
|
25
|
-
{profile}
|
26
|
-
现在是2024年1月。
|
27
|
-
你需要为下一周的基本生活购买必需品。
|
28
|
-
'''
|
29
|
-
dialogs.append(encap_msg(system_prompt, 'system'))
|
30
|
-
actions_format = ['''{{'商品': 购买的商品的列表,'购买量': 每个商品的购买量,一个列表, '解释': '这种购买方式的原因'}}''']
|
31
|
-
actions_candidates = ['''【食品】
|
32
|
-
米:10元/公斤
|
33
|
-
面粉:7.5元/公斤
|
34
|
-
新鲜蔬菜(如菠菜):7元/500克
|
35
|
-
水果(如苹果):15元/公斤
|
36
|
-
猪肉:30元/公斤
|
37
|
-
鸡肉:20元/公斤
|
38
|
-
鸡蛋:1.5元/个
|
39
|
-
牛奶:10元/升''',
|
40
|
-
'''【清洁用品】
|
41
|
-
洗衣液:30元/瓶
|
42
|
-
洗洁精:20元/瓶
|
43
|
-
垃圾袋:0.3元/个''',
|
44
|
-
'''【个人护理用品】
|
45
|
-
牙膏:10元/支
|
46
|
-
洗发水:30元/瓶
|
47
|
-
沐浴露:35元/瓶
|
48
|
-
面巾纸:5元/包''',
|
49
|
-
'''【其他】
|
50
|
-
矿泉水:1.7元/瓶
|
51
|
-
面包:8元/个
|
52
|
-
辣条:3元/包''']
|
53
|
-
|
54
|
-
user_prompt = f'''
|
55
|
-
首先确定你的消费预算。以如下格式回答,不要有冗余的文本!
|
56
|
-
{{'消费预算': 一个代表购买必需品需要消耗的钱的数量的数字}}
|
57
|
-
'''
|
58
|
-
dialogs.append(encap_msg(user_prompt))
|
59
|
-
# * 对接一:确定消费预算
|
60
|
-
self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), '我正在确定消费预算......', None, None)])
|
61
|
-
msg = self._agent._soul.text_request(dialogs)
|
62
|
-
self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), f'我的消费预算是: {msg}'), None, None])
|
63
|
-
|
64
|
-
dialogs.append(encap_msg(msg, 'assistant'))
|
65
|
-
|
66
|
-
# * 对接二:购物选择
|
67
|
-
for cand in actions_candidates:
|
68
|
-
user_prompt = f'''
|
69
|
-
购物中心里有
|
70
|
-
{cand}
|
71
|
-
你要买哪些商品,以如下格式回答,不要有冗余的文本!
|
72
|
-
{actions_format[0]}
|
73
|
-
'''
|
74
|
-
self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), f'我看到了\n {cand}', None, None)])
|
75
|
-
dialogs.append(encap_msg(user_prompt))
|
76
|
-
msg = self._agent._soul.text_request(dialogs)
|
77
|
-
self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), f'我的购买选择是: {msg}', None, None)])
|
78
|
-
dialogs.append(encap_msg(msg, 'assistant'))
|
79
|
-
|
80
|
-
self._agent.Hub.Update([AgentMessage(self._agent.Hub._agent_id, int(time.time()*1000), '购物完成', None, None)])
|