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
@@ -0,0 +1,165 @@
1
+ """
2
+ Agent Profile
3
+ """
4
+
5
+ from copy import deepcopy
6
+ from typing import (Any, Callable, Dict, List, Optional, Sequence, Tuple,
7
+ Union, cast)
8
+
9
+ from ..utils.decorators import lock_decorator
10
+ from .const import *
11
+ from .memory_base import MemoryBase, MemoryUnit
12
+ from .utils import convert_msg_to_sequence
13
+
14
+
15
+ class ProfileMemoryUnit(MemoryUnit):
16
+ def __init__(
17
+ self,
18
+ content: Optional[Dict] = None,
19
+ activate_timestamp: bool = False,
20
+ ) -> None:
21
+ super().__init__(
22
+ content=content,
23
+ required_attributes=PROFILE_ATTRIBUTES,
24
+ activate_timestamp=activate_timestamp,
25
+ )
26
+
27
+
28
+ class ProfileMemory(MemoryBase):
29
+ def __init__(
30
+ self,
31
+ msg: Optional[
32
+ Union[ProfileMemoryUnit, Sequence[ProfileMemoryUnit], Dict, Sequence[Dict]]
33
+ ] = None,
34
+ activate_timestamp: bool = False,
35
+ ) -> None:
36
+ super().__init__()
37
+ if msg is None:
38
+ msg = deepcopy(PROFILE_ATTRIBUTES)
39
+ self.activate_timestamp = activate_timestamp
40
+ msg = convert_msg_to_sequence(
41
+ msg,
42
+ sequence_type=ProfileMemoryUnit,
43
+ activate_timestamp=self.activate_timestamp,
44
+ )
45
+ for unit in msg:
46
+ self._memories[unit] = {}
47
+
48
+ @lock_decorator
49
+ async def add(
50
+ self, msg: Union[ProfileMemoryUnit, Sequence[ProfileMemoryUnit]]
51
+ ) -> None:
52
+ _memories = self._memories
53
+ msg = convert_msg_to_sequence(
54
+ msg,
55
+ sequence_type=ProfileMemoryUnit,
56
+ activate_timestamp=self.activate_timestamp,
57
+ )
58
+ for unit in msg:
59
+ if unit not in _memories:
60
+ _memories[unit] = {}
61
+
62
+ @lock_decorator
63
+ async def pop(self, index: int) -> ProfileMemoryUnit:
64
+
65
+ _memories = self._memories
66
+ try:
67
+ pop_unit = list(_memories.keys())[index]
68
+ _memories.pop(pop_unit)
69
+
70
+ return pop_unit
71
+ except IndexError as e:
72
+
73
+ raise ValueError(f"Index {index} not in memory!")
74
+
75
+ @lock_decorator
76
+ async def load(
77
+ self,
78
+ snapshots: Union[Dict, Sequence[Dict]],
79
+ reset_memory: bool = False,
80
+ ) -> None:
81
+ if reset_memory:
82
+ self._memories = {}
83
+ msg = convert_msg_to_sequence(
84
+ snapshots,
85
+ sequence_type=ProfileMemoryUnit,
86
+ activate_timestamp=self.activate_timestamp,
87
+ )
88
+ for unit in msg:
89
+ if unit not in self._memories:
90
+ self._memories[unit] = {}
91
+
92
+ @lock_decorator
93
+ async def export(
94
+ self,
95
+ ) -> Sequence[Dict]:
96
+ _res = []
97
+ for m in self._memories.keys():
98
+ m = cast(ProfileMemoryUnit, m)
99
+ _dict_values = await m.dict_values()
100
+ _res.append(_dict_values)
101
+
102
+ return _res
103
+
104
+ async def reset(self) -> None:
105
+ self._memories = {}
106
+
107
+ # interact
108
+ @lock_decorator
109
+ async def get(self, key: Any):
110
+ _latest_memories = self._fetch_recent_memory()
111
+ _latest_memory: ProfileMemoryUnit = _latest_memories[-1]
112
+ return _latest_memory[key]
113
+
114
+ @lock_decorator
115
+ async def get_top_k(
116
+ self,
117
+ key: Any,
118
+ metric: Callable[[Any], Any],
119
+ top_k: Optional[int] = None,
120
+ preserve_order: bool = True,
121
+ ) -> Union[Sequence[Any], Any]:
122
+ _latest_memories = self._fetch_recent_memory()
123
+ _latest_memory: ProfileMemoryUnit = _latest_memories[-1]
124
+ _top_k = await _latest_memory.top_k_values(key, metric, top_k, preserve_order)
125
+
126
+ return _top_k
127
+
128
+ @lock_decorator
129
+ async def update(self, key: Any, value: Any, store_snapshot: bool = False):
130
+ _latest_memories = self._fetch_recent_memory()
131
+ _latest_memory: ProfileMemoryUnit = _latest_memories[-1]
132
+ if not store_snapshot:
133
+ # write in place
134
+ await _latest_memory.update({key: value})
135
+
136
+ else:
137
+ # insert new unit
138
+ _dict_values = await _latest_memory.dict_values()
139
+ _content = deepcopy(
140
+ {k: v for k, v in _dict_values.items() if k not in {TIME_STAMP_KEY}}
141
+ )
142
+ _content.update({key: value})
143
+ msg = ProfileMemoryUnit(_content, self.activate_timestamp)
144
+ for unit in [msg]:
145
+ if unit not in self._memories:
146
+ self._memories[unit] = {}
147
+
148
+ @lock_decorator
149
+ async def update_dict(self, to_update_dict: Dict, store_snapshot: bool = False):
150
+ _latest_memories = self._fetch_recent_memory()
151
+ _latest_memory: ProfileMemoryUnit = _latest_memories[-1]
152
+ if not store_snapshot:
153
+ # write in place
154
+ await _latest_memory.update(to_update_dict)
155
+ else:
156
+ # insert new unit
157
+ _dict_values = await _latest_memory.dict_values()
158
+ _content = deepcopy(
159
+ {k: v for k, v in _dict_values.items() if k not in {TIME_STAMP_KEY}}
160
+ )
161
+ _content.update(to_update_dict)
162
+ msg = ProfileMemoryUnit(_content, self.activate_timestamp)
163
+ for unit in [msg]:
164
+ if unit not in self._memories:
165
+ self._memories[unit] = {}
@@ -0,0 +1,165 @@
1
+ """
2
+ Self Define Data
3
+ """
4
+
5
+ from copy import deepcopy
6
+ from typing import (Any, Callable, Dict, List, Optional, Sequence, Tuple,
7
+ Union, cast)
8
+
9
+ from ..utils.decorators import lock_decorator
10
+ from .const import *
11
+ from .memory_base import MemoryBase, MemoryUnit
12
+ from .utils import convert_msg_to_sequence
13
+
14
+
15
+ class DynamicMemoryUnit(MemoryUnit):
16
+ def __init__(
17
+ self,
18
+ content: Optional[Dict] = None,
19
+ required_attributes: Optional[Dict] = None,
20
+ activate_timestamp: bool = False,
21
+ ) -> None:
22
+ super().__init__(
23
+ content=content,
24
+ required_attributes=required_attributes,
25
+ activate_timestamp=activate_timestamp,
26
+ )
27
+
28
+
29
+ class DynamicMemory(MemoryBase):
30
+
31
+ def __init__(
32
+ self,
33
+ required_attributes: Dict[Any, Any],
34
+ activate_timestamp: bool = False,
35
+ ) -> None:
36
+ super().__init__()
37
+ self._required_attributes = deepcopy(required_attributes)
38
+ self.activate_timestamp = activate_timestamp
39
+ msg = DynamicMemoryUnit(
40
+ self._required_attributes, None, self.activate_timestamp
41
+ )
42
+ self._memories[msg] = {}
43
+
44
+ @lock_decorator
45
+ async def add(
46
+ self, msg: Union[DynamicMemoryUnit, Sequence[DynamicMemoryUnit]]
47
+ ) -> None:
48
+ _memories = self._memories
49
+ msg = convert_msg_to_sequence(
50
+ msg,
51
+ sequence_type=DynamicMemoryUnit,
52
+ activate_timestamp=self.activate_timestamp,
53
+ )
54
+ for unit in msg:
55
+ if unit not in _memories:
56
+ _memories[unit] = {}
57
+
58
+ @lock_decorator
59
+ async def pop(self, index: int) -> DynamicMemoryUnit:
60
+ _memories = self._memories
61
+ try:
62
+ pop_unit = list(_memories.keys())[index]
63
+ _memories.pop(pop_unit)
64
+
65
+ return pop_unit
66
+ except IndexError as e:
67
+
68
+ raise ValueError(f"Index {index} not in memory!")
69
+
70
+ @lock_decorator
71
+ async def load(
72
+ self,
73
+ snapshots: Union[Dict, Sequence[Dict]],
74
+ reset_memory: bool = False,
75
+ ) -> None:
76
+ if reset_memory:
77
+ self._memories = {}
78
+ msg = convert_msg_to_sequence(
79
+ snapshots,
80
+ sequence_type=DynamicMemoryUnit,
81
+ activate_timestamp=self.activate_timestamp,
82
+ )
83
+ for unit in msg:
84
+ if unit not in self._memories:
85
+ self._memories[unit] = {}
86
+
87
+ @lock_decorator
88
+ async def export(
89
+ self,
90
+ ) -> Sequence[Dict]:
91
+ _res = []
92
+ for m in self._memories.keys():
93
+ m = cast(DynamicMemoryUnit, m)
94
+ _dict_values = await m.dict_values()
95
+ _res.append(_dict_values)
96
+
97
+ return _res
98
+
99
+ async def reset(self) -> None:
100
+ self._memories = {}
101
+
102
+ # interact
103
+ @lock_decorator
104
+ async def get(self, key: Any):
105
+ _latest_memories = self._fetch_recent_memory()
106
+ _latest_memory: DynamicMemoryUnit = _latest_memories[-1]
107
+
108
+ return _latest_memory[key]
109
+
110
+ @lock_decorator
111
+ async def get_top_k(
112
+ self,
113
+ key: Any,
114
+ metric: Callable[[Any], Any],
115
+ top_k: Optional[int] = None,
116
+ preserve_order: bool = True,
117
+ ) -> Union[Sequence[Any], Any]:
118
+ _latest_memories = self._fetch_recent_memory()
119
+ _latest_memory: DynamicMemoryUnit = _latest_memories[-1]
120
+ _top_k = await _latest_memory.top_k_values(key, metric, top_k, preserve_order)
121
+
122
+ return _top_k
123
+
124
+ @lock_decorator
125
+ async def update(self, key: Any, value: Any, store_snapshot: bool = False):
126
+ _latest_memories = self._fetch_recent_memory()
127
+ _latest_memory: DynamicMemoryUnit = _latest_memories[-1]
128
+ if not store_snapshot:
129
+ # write in place
130
+ await _latest_memory.update({key: value})
131
+
132
+ else:
133
+ # insert new unit
134
+ _dict_values = await _latest_memory.dict_values()
135
+ _content = deepcopy(
136
+ {k: v for k, v in _dict_values.items() if k not in {TIME_STAMP_KEY}}
137
+ )
138
+ _content.update({key: value})
139
+ msg = DynamicMemoryUnit(
140
+ _content, self._required_attributes, self.activate_timestamp
141
+ )
142
+ for unit in [msg]:
143
+ if unit not in self._memories:
144
+ self._memories[unit] = {}
145
+
146
+ @lock_decorator
147
+ async def update_dict(self, to_update_dict: Dict, store_snapshot: bool = False):
148
+ _latest_memories = self._fetch_recent_memory()
149
+ _latest_memory: DynamicMemoryUnit = _latest_memories[-1]
150
+ if not store_snapshot:
151
+ # write in place
152
+ await _latest_memory.update(to_update_dict)
153
+ else:
154
+ # insert new unit
155
+ _dict_values = await _latest_memory.dict_values()
156
+ _content = deepcopy(
157
+ {k: v for k, v in _dict_values.items() if k not in {TIME_STAMP_KEY}}
158
+ )
159
+ _content.update(to_update_dict)
160
+ msg = DynamicMemoryUnit(
161
+ _content, self._required_attributes, self.activate_timestamp
162
+ )
163
+ for unit in [msg]:
164
+ if unit not in self._memories:
165
+ self._memories[unit] = {}
@@ -0,0 +1,173 @@
1
+ """
2
+ Agent State
3
+ """
4
+
5
+ from copy import deepcopy
6
+ from typing import (Any, Callable, Dict, List, Optional, Sequence, Tuple,
7
+ Union, cast)
8
+
9
+ from ..utils.decorators import lock_decorator
10
+ from .const import *
11
+ from .memory_base import MemoryBase, MemoryUnit
12
+ from .utils import convert_msg_to_sequence
13
+
14
+
15
+ class StateMemoryUnit(MemoryUnit):
16
+ def __init__(
17
+ self,
18
+ content: Optional[Dict] = None,
19
+ activate_timestamp: bool = False,
20
+ ) -> None:
21
+ super().__init__(
22
+ content=content,
23
+ required_attributes=STATE_ATTRIBUTES,
24
+ activate_timestamp=activate_timestamp,
25
+ )
26
+
27
+
28
+ class StateMemory(MemoryBase):
29
+ def __init__(
30
+ self,
31
+ msg: Optional[
32
+ Union[MemoryUnit, Sequence[MemoryUnit], Dict, Sequence[Dict]]
33
+ ] = None,
34
+ activate_timestamp: bool = False,
35
+ ) -> None:
36
+ super().__init__()
37
+ if msg is None:
38
+ msg = deepcopy(STATE_ATTRIBUTES)
39
+ self.activate_timestamp = activate_timestamp
40
+ msg = convert_msg_to_sequence(
41
+ msg,
42
+ sequence_type=StateMemoryUnit,
43
+ activate_timestamp=self.activate_timestamp,
44
+ )
45
+ for unit in msg:
46
+ self._memories[unit] = {}
47
+
48
+ @lock_decorator
49
+ async def add(self, msg: Union[MemoryUnit, Sequence[MemoryUnit]]) -> None:
50
+
51
+ _memories = self._memories
52
+ msg = convert_msg_to_sequence(
53
+ msg,
54
+ sequence_type=StateMemoryUnit,
55
+ activate_timestamp=self.activate_timestamp,
56
+ )
57
+ for unit in msg:
58
+ if unit not in _memories:
59
+ _memories[unit] = {}
60
+
61
+ @lock_decorator
62
+ async def pop(self, index: int) -> MemoryUnit:
63
+
64
+ _memories = self._memories
65
+ try:
66
+ pop_unit = list(_memories.keys())[index]
67
+ _memories.pop(pop_unit)
68
+
69
+ return pop_unit
70
+ except IndexError as e:
71
+
72
+ raise ValueError(f"Index {index} not in memory!")
73
+
74
+ @lock_decorator
75
+ async def load(
76
+ self,
77
+ snapshots: Union[Dict, Sequence[Dict]],
78
+ reset_memory: bool = False,
79
+ ) -> None:
80
+
81
+ if reset_memory:
82
+ self._memories = {}
83
+ msg = convert_msg_to_sequence(
84
+ snapshots,
85
+ sequence_type=StateMemoryUnit,
86
+ activate_timestamp=self.activate_timestamp,
87
+ )
88
+ for unit in msg:
89
+ if unit not in self._memories:
90
+ self._memories[unit] = {}
91
+
92
+ @lock_decorator
93
+ async def export(
94
+ self,
95
+ ) -> Sequence[Dict]:
96
+
97
+ _res = []
98
+ for m in self._memories.keys():
99
+ m = cast(StateMemoryUnit, m)
100
+ _dict_values = await m.dict_values()
101
+ _res.append(_dict_values)
102
+
103
+ return _res
104
+
105
+ async def reset(self) -> None:
106
+
107
+ self._memories = {}
108
+
109
+ # interact
110
+ @lock_decorator
111
+ async def get(self, key: Any):
112
+
113
+ _latest_memories = self._fetch_recent_memory()
114
+ _latest_memory: StateMemoryUnit = _latest_memories[-1]
115
+
116
+ return _latest_memory[key]
117
+
118
+ @lock_decorator
119
+ async def get_top_k(
120
+ self,
121
+ key: Any,
122
+ metric: Callable[[Any], Any],
123
+ top_k: Optional[int] = None,
124
+ preserve_order: bool = True,
125
+ ) -> Union[Sequence[Any], Any]:
126
+
127
+ _latest_memories = self._fetch_recent_memory()
128
+ _latest_memory: StateMemoryUnit = _latest_memories[-1]
129
+ _top_k = await _latest_memory.top_k_values(key, metric, top_k, preserve_order)
130
+
131
+ return _top_k
132
+
133
+ @lock_decorator
134
+ async def update(self, key: Any, value: Any, store_snapshot: bool = False):
135
+
136
+ _latest_memories = self._fetch_recent_memory()
137
+ _latest_memory: StateMemoryUnit = _latest_memories[-1]
138
+ if not store_snapshot:
139
+ # write in place
140
+ await _latest_memory.update({key: value})
141
+
142
+ else:
143
+ # insert new unit
144
+ _dict_values = await _latest_memory.dict_values()
145
+ _content = deepcopy(
146
+ {k: v for k, v in _dict_values.items() if k not in {TIME_STAMP_KEY}}
147
+ )
148
+ _content.update({key: value})
149
+ msg = StateMemoryUnit(_content, self.activate_timestamp)
150
+ for unit in [msg]:
151
+ if unit not in self._memories:
152
+ self._memories[unit] = {}
153
+
154
+ @lock_decorator
155
+ async def update_dict(self, to_update_dict: Dict, store_snapshot: bool = False):
156
+
157
+ _latest_memories = self._fetch_recent_memory()
158
+ _latest_memory: StateMemoryUnit = _latest_memories[-1]
159
+ if not store_snapshot:
160
+ # write in place
161
+ await _latest_memory.update(to_update_dict)
162
+
163
+ else:
164
+ # insert new unit
165
+ _dict_values = await _latest_memory.dict_values()
166
+ _content = deepcopy(
167
+ {k: v for k, v in _dict_values.items() if k not in {TIME_STAMP_KEY}}
168
+ )
169
+ _content.update(to_update_dict)
170
+ msg = StateMemoryUnit(_content, self.activate_timestamp)
171
+ for unit in [msg]:
172
+ if unit not in self._memories:
173
+ self._memories[unit] = {}
@@ -0,0 +1,27 @@
1
+ from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
2
+
3
+ from .memory_base import MemoryUnit
4
+
5
+
6
+ def convert_msg_to_sequence(
7
+ msg: Union[Any, Sequence[Any]],
8
+ sequence_type=MemoryUnit,
9
+ activate_timestamp: bool = False,
10
+ ) -> Sequence[Any]:
11
+ # Convert the input message to a sequence if it is not already one
12
+ if not isinstance(msg, Sequence):
13
+ _sequence_msg = [msg]
14
+ else:
15
+ _sequence_msg = msg
16
+
17
+ # Initialize an empty list to store the converted MemoryUnit objects
18
+ _sequence_unit = []
19
+
20
+ # Iterate over each unit in the sequence
21
+ for unit in _sequence_msg:
22
+ # If the unit is not already a MemoryUnit, convert it to one
23
+ if not isinstance(unit, sequence_type):
24
+ unit = sequence_type(content=unit, activate_timestamp=activate_timestamp)
25
+ _sequence_unit.append(unit)
26
+
27
+ return _sequence_unit
File without changes
@@ -0,0 +1,7 @@
1
+ """
2
+ 城市智能体模拟器模块
3
+ """
4
+
5
+ from .simulation import AgentSimulation
6
+
7
+ __all__ = ["AgentSimulation"]
@@ -0,0 +1,36 @@
1
+ from dataclasses import dataclass
2
+ from datetime import datetime
3
+ from typing import List, Optional
4
+
5
+ @dataclass
6
+ class InterviewRecord:
7
+ """采访记录"""
8
+ timestamp: datetime
9
+ agent_name: str
10
+ question: str
11
+ response: str
12
+ blocking: bool
13
+
14
+ class InterviewManager:
15
+ """采访管理器"""
16
+ def __init__(self):
17
+ self._history: List[InterviewRecord] = []
18
+
19
+ def add_record(self, agent_name: str, question: str, response: str, blocking: bool):
20
+ """添加采访记录"""
21
+ record = InterviewRecord(
22
+ timestamp=datetime.now(),
23
+ agent_name=agent_name,
24
+ question=question,
25
+ response=response,
26
+ blocking=blocking
27
+ )
28
+ self._history.append(record)
29
+
30
+ def get_agent_history(self, agent_name: str) -> List[InterviewRecord]:
31
+ """获取指定智能体的采访历史"""
32
+ return [r for r in self._history if r.agent_name == agent_name]
33
+
34
+ def get_recent_history(self, limit: int = 10) -> List[InterviewRecord]:
35
+ """获取最近的采访记录"""
36
+ return sorted(self._history, key=lambda x: x.timestamp, reverse=True)[:limit]