pycityagent 2.0.0a20__py3-none-any.whl → 2.0.0a22__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.
@@ -0,0 +1,139 @@
1
+ import asyncio
2
+ from collections import defaultdict
3
+ from typing import Any
4
+
5
+ import psycopg
6
+ import psycopg.sql
7
+ import ray
8
+ from psycopg.rows import dict_row
9
+
10
+ from ...utils.decorators import lock_decorator
11
+ from ...utils.pg_query import PGSQL_DICT
12
+
13
+
14
+ def create_pg_tables(exp_id: str, dsn: str):
15
+ for table_type, exec_strs in PGSQL_DICT.items():
16
+ table_name = f"socialcity_{exp_id.replace('-', '_')}_{table_type}"
17
+ # # debug str
18
+ # for _str in [f"DROP TABLE IF EXISTS {table_name}"] + [
19
+ # _exec_str.format(table_name=table_name) for _exec_str in exec_strs
20
+ # ]:
21
+ # print(_str)
22
+ with psycopg.connect(dsn) as conn:
23
+ with conn.cursor() as cur:
24
+ # delete table
25
+ cur.execute(f"DROP TABLE IF EXISTS {table_name}") # type:ignore
26
+ conn.commit()
27
+ # create table
28
+ for _exec_str in exec_strs:
29
+ cur.execute(_exec_str.format(table_name=table_name))
30
+ conn.commit()
31
+
32
+
33
+ @ray.remote
34
+ class PgWriter:
35
+ def __init__(self, exp_id: str, dsn: str):
36
+ self.exp_id = exp_id
37
+ self._dsn = dsn
38
+ # self._lock = asyncio.Lock()
39
+
40
+ # @lock_decorator
41
+ async def async_write_dialog(self, rows: list[tuple]):
42
+ _tuple_types = [str, int, float, int, str, str, str, None]
43
+ table_name = f"socialcity_{self.exp_id.replace('-', '_')}_agent_dialog"
44
+ # 将数据插入数据库
45
+ async with await psycopg.AsyncConnection.connect(self._dsn) as aconn:
46
+ copy_sql = psycopg.sql.SQL(
47
+ "COPY {} (id, day, t, type, speaker, content, created_at) FROM STDIN"
48
+ ).format(psycopg.sql.Identifier(table_name))
49
+ async with aconn.cursor() as cur:
50
+ async with cur.copy(copy_sql) as copy:
51
+ for row in rows:
52
+ _row = [
53
+ _type(r) if _type is not None else r
54
+ for (_type, r) in zip(_tuple_types, row)
55
+ ]
56
+ await copy.write_row(_row)
57
+
58
+ # @lock_decorator
59
+ async def async_write_status(self, rows: list[tuple]):
60
+ _tuple_types = [str, int, float, float, float, int, str, str, None]
61
+ table_name = f"socialcity_{self.exp_id.replace('-', '_')}_agent_status"
62
+ async with await psycopg.AsyncConnection.connect(self._dsn) as aconn:
63
+ copy_sql = psycopg.sql.SQL(
64
+ "COPY {} (id, day, t, lng, lat, parent_id, action, status, created_at) FROM STDIN"
65
+ ).format(psycopg.sql.Identifier(table_name))
66
+ async with aconn.cursor() as cur:
67
+ async with cur.copy(copy_sql) as copy:
68
+ for row in rows:
69
+ _row = [
70
+ _type(r) if _type is not None else r
71
+ for (_type, r) in zip(_tuple_types, row)
72
+ ]
73
+ await copy.write_row(_row)
74
+
75
+ # @lock_decorator
76
+ async def async_write_profile(self, rows: list[tuple]):
77
+ _tuple_types = [str, str, str]
78
+ table_name = f"socialcity_{self.exp_id.replace('-', '_')}_agent_profile"
79
+ async with await psycopg.AsyncConnection.connect(self._dsn) as aconn:
80
+ copy_sql = psycopg.sql.SQL("COPY {} (id, name, profile) FROM STDIN").format(
81
+ psycopg.sql.Identifier(table_name)
82
+ )
83
+ async with aconn.cursor() as cur:
84
+ async with cur.copy(copy_sql) as copy:
85
+ for row in rows:
86
+ _row = [
87
+ _type(r) if _type is not None else r
88
+ for (_type, r) in zip(_tuple_types, row)
89
+ ]
90
+ await copy.write_row(_row)
91
+
92
+ # @lock_decorator
93
+ async def async_write_survey(self, rows: list[tuple]):
94
+ _tuple_types = [str, int, float, str, str, None]
95
+ table_name = f"socialcity_{self.exp_id.replace('-', '_')}_agent_survey"
96
+ async with await psycopg.AsyncConnection.connect(self._dsn) as aconn:
97
+ copy_sql = psycopg.sql.SQL(
98
+ "COPY {} (id, day, t, survey_id, result, created_at) FROM STDIN"
99
+ ).format(psycopg.sql.Identifier(table_name))
100
+ async with aconn.cursor() as cur:
101
+ async with cur.copy(copy_sql) as copy:
102
+ for row in rows:
103
+ _row = [
104
+ _type(r) if _type is not None else r
105
+ for (_type, r) in zip(_tuple_types, row)
106
+ ]
107
+ await copy.write_row(_row)
108
+
109
+ # @lock_decorator
110
+ async def async_update_exp_info(self, exp_info: dict[str, Any]):
111
+ # timestamp不做类型转换
112
+ TO_UPDATE_EXP_INFO_KEYS_AND_TYPES = [
113
+ ("id", str),
114
+ ("name", str),
115
+ ("num_day", int),
116
+ ("status", int),
117
+ ("cur_day", int),
118
+ ("cur_t", float),
119
+ ("config", str),
120
+ ("error", str),
121
+ ("created_at", None),
122
+ ("updated_at", None),
123
+ ]
124
+ table_name = f"socialcity_{self.exp_id.replace('-', '_')}_experiment"
125
+ async with await psycopg.AsyncConnection.connect(self._dsn) as aconn:
126
+ async with aconn.cursor(row_factory=dict_row) as cur:
127
+ # UPDATE
128
+ columns = ", ".join(
129
+ f"{key} = %s" for key, _ in TO_UPDATE_EXP_INFO_KEYS_AND_TYPES
130
+ )
131
+ update_sql = psycopg.sql.SQL(
132
+ f"UPDATE {{}} SET {columns} WHERE id = %s" # type:ignore
133
+ ).format(psycopg.sql.Identifier(table_name))
134
+ params = [
135
+ _type(exp_info[key]) if _type is not None else exp_info[key]
136
+ for key, _type in TO_UPDATE_EXP_INFO_KEYS_AND_TYPES
137
+ ] + [self.exp_id]
138
+ await cur.execute(update_sql, params)
139
+ await aconn.commit()
@@ -1,6 +1,6 @@
1
1
  import json
2
2
  import logging
3
- from typing import Any, Dict
3
+ from typing import Any
4
4
 
5
5
  from .parser_base import ParserBase
6
6
 
@@ -67,14 +67,14 @@ class JsonDictParser(JsonObjectParser):
67
67
  """Initialize the JsonDictParser with default tags."""
68
68
  super().__init__()
69
69
 
70
- def parse(self, response: str) -> Dict:
70
+ def parse(self, response: str) -> dict:
71
71
  """Parse the response string to extract and return a JSON object as a dictionary.
72
72
 
73
73
  Parameters:
74
74
  response (str): The response string containing the JSON object.
75
75
 
76
76
  Returns:
77
- Dict: The parsed JSON object as a dictionary.
77
+ dict: The parsed JSON object as a dictionary.
78
78
  """
79
79
  parsed_json = super().parse(response)
80
80
  if not isinstance(parsed_json, dict):
@@ -0,0 +1,80 @@
1
+ from typing import Any
2
+
3
+ PGSQL_DICT: dict[str, list[Any]] = {
4
+ # Experiment
5
+ "experiment": [
6
+ """
7
+ CREATE TABLE IF NOT EXISTS {table_name} (
8
+ id UUID PRIMARY KEY,
9
+ name TEXT,
10
+ num_day INT4,
11
+ status INT4,
12
+ cur_day INT4,
13
+ cur_t FLOAT,
14
+ config TEXT,
15
+ error TEXT,
16
+ created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
17
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
18
+ )
19
+ """,
20
+ ],
21
+ # Agent Profile
22
+ "agent_profile": [
23
+ """
24
+ CREATE TABLE IF NOT EXISTS {table_name} (
25
+ id UUID PRIMARY KEY,
26
+ name TEXT,
27
+ profile JSONB
28
+ )
29
+ """,
30
+ ],
31
+ # Agent Dialog
32
+ "agent_dialog": [
33
+ """
34
+ CREATE TABLE IF NOT EXISTS {table_name} (
35
+ id UUID,
36
+ day INT4,
37
+ t FLOAT,
38
+ type INT4,
39
+ speaker TEXT,
40
+ content TEXT,
41
+ created_at TIMESTAMPTZ
42
+ )
43
+ """,
44
+ "CREATE INDEX {table_name}_id_idx ON {table_name} (id)",
45
+ "CREATE INDEX {table_name}_day_t_idx ON {table_name} (day,t)",
46
+ ],
47
+ # Agent Status
48
+ "agent_status": [
49
+ """
50
+ CREATE TABLE IF NOT EXISTS {table_name} (
51
+ id UUID,
52
+ day INT4,
53
+ t FLOAT,
54
+ lng DOUBLE PRECISION,
55
+ lat DOUBLE PRECISION,
56
+ parent_id INT4,
57
+ action TEXT,
58
+ status JSONB,
59
+ created_at TIMESTAMPTZ
60
+ )
61
+ """,
62
+ "CREATE INDEX {table_name}_id_idx ON {table_name} (id)",
63
+ "CREATE INDEX {table_name}_day_t_idx ON {table_name} (day,t)",
64
+ ],
65
+ # Agent Survey
66
+ "agent_survey": [
67
+ """
68
+ CREATE TABLE IF NOT EXISTS {table_name} (
69
+ id UUID,
70
+ day INT4,
71
+ t FLOAT,
72
+ survey_id UUID,
73
+ result JSONB,
74
+ created_at TIMESTAMPTZ
75
+ )
76
+ """,
77
+ "CREATE INDEX {table_name}_id_idx ON {table_name} (id)",
78
+ "CREATE INDEX {table_name}_day_t_idx ON {table_name} (day,t)",
79
+ ],
80
+ }
@@ -1,7 +1,8 @@
1
1
  import asyncio
2
2
  import functools
3
3
  import inspect
4
- from typing import Any, Callable, Coroutine, Optional, Union
4
+ from collections.abc import Awaitable, Callable, Coroutine
5
+ from typing import Any, Optional, Union
5
6
 
6
7
  from ..environment.simulator import Simulator
7
8
  from ..llm import LLM
@@ -1,6 +1,8 @@
1
1
  import time
2
+ from collections import defaultdict
3
+ from collections.abc import Callable, Sequence
2
4
  from typing import Any, Optional, Union
3
- from collections.abc import Callable
5
+
4
6
  from mlflow.entities import Metric
5
7
 
6
8
  from ..agent import Agent
@@ -190,33 +192,38 @@ class ResetAgentPosition(Tool):
190
192
  class ExportMlflowMetrics(Tool):
191
193
  def __init__(self, log_batch_size: int = 100) -> None:
192
194
  self._log_batch_size = log_batch_size
193
- # TODO:support other log types
194
- self.metric_log_cache: list[Metric] = []
195
+ # TODO: support other log types
196
+ self.metric_log_cache: dict[str, list[Metric]] = defaultdict(list)
195
197
 
196
198
  async def __call__(
197
199
  self,
198
- metric: Union[Metric, dict],
200
+ metric: Union[Sequence[Union[Metric, dict]], Union[Metric, dict]],
199
201
  clear_cache: bool = False,
200
202
  ):
201
203
  agent = self.agent
202
204
  batch_size = self._log_batch_size
203
- if len(self.metric_log_cache) > batch_size:
204
- client = agent.mlflow_client
205
- await client.log_batch(
206
- metrics=self.metric_log_cache[:batch_size],
207
- )
208
- self.metric_log_cache = self.metric_log_cache[batch_size:]
209
- else:
210
- if isinstance(metric, Metric):
211
- self.metric_log_cache.append(metric)
205
+ if not isinstance(metric, Sequence):
206
+ metric = [metric]
207
+ for _metric in metric:
208
+ if isinstance(_metric, Metric):
209
+ item = _metric
210
+ metric_key = item.key
212
211
  else:
213
- _metric = Metric(
214
- key=metric["key"],
215
- value=metric["value"],
216
- timestamp=metric.get("timestamp", int(1000 * time.time())),
217
- step=metric["step"],
212
+ item = Metric(
213
+ key=_metric["key"],
214
+ value=_metric["value"],
215
+ timestamp=_metric.get("timestamp", int(1000 * time.time())),
216
+ step=_metric["step"],
218
217
  )
219
- self.metric_log_cache.append(_metric)
218
+ metric_key = _metric["key"]
219
+ self.metric_log_cache[metric_key].append(item)
220
+ for metric_key, _cache in self.metric_log_cache.items():
221
+ if len(_cache) > batch_size:
222
+ client = agent.mlflow_client
223
+ await client.log_batch(
224
+ metrics=_cache[:batch_size],
225
+ )
226
+ _cache = _cache[batch_size:]
220
227
  if clear_cache:
221
228
  await self._clear_cache()
222
229
 
@@ -225,8 +232,9 @@ class ExportMlflowMetrics(Tool):
225
232
  ):
226
233
  agent = self.agent
227
234
  client = agent.mlflow_client
228
- if len(self.metric_log_cache) > 0:
229
- await client.log_batch(
230
- metrics=self.metric_log_cache,
231
- )
232
- self.metric_log_cache = []
235
+ for metric_key, _cache in self.metric_log_cache.items():
236
+ if len(_cache) > 0:
237
+ await client.log_batch(
238
+ metrics=_cache,
239
+ )
240
+ _cache = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pycityagent
3
- Version: 2.0.0a20
3
+ Version: 2.0.0a22
4
4
  Summary: LLM-based城市环境agent构建库
5
5
  License: MIT
6
6
  Author: Yuwei Yan
@@ -1,5 +1,5 @@
1
1
  pycityagent/__init__.py,sha256=EDxt3Su3lH1IMh9suNw7GeGL7UrXeWiZTw5KWNznDzc,637
2
- pycityagent/agent.py,sha256=HRFAG_iM1q3nvXtV0T-Dz01foOtty4IWka7h4WD97CU,24268
2
+ pycityagent/agent.py,sha256=TGW4vyaYBnNxYkr22FhGPwex3dLIeq3F-2rnELidNPA,28670
3
3
  pycityagent/economy/__init__.py,sha256=aonY4WHnx-6EGJ4WKrx4S-2jAkYNLtqUA04jp6q8B7w,75
4
4
  pycityagent/economy/econ_client.py,sha256=GuHK9ZBnhqW3Z7F8ViDJn_iN73yOBbbwFyJv1wLEBDk,12211
5
5
  pycityagent/environment/__init__.py,sha256=awHxlOud-btWbk0FCS4RmGJ13W84oVCkbGfcrhKqihA,240
@@ -11,16 +11,16 @@ pycityagent/environment/sence/static.py,sha256=9s7jz8HitstTrk-GqpnVB26oPrjuTyNeL
11
11
  pycityagent/environment/sidecar/__init__.py,sha256=RFbOf40aYBP4WwRpFkua5tlRE_OtMcMNyp1Lew_aaAU,235
12
12
  pycityagent/environment/sidecar/sidecarv2.py,sha256=beKlYZgt38EQbV1x6NWQo7xVXyB-5QHfbwJexyXu7Tg,3252
13
13
  pycityagent/environment/sim/__init__.py,sha256=JVG6sSD2Hbohl1TtKjuQi7_M7tKMrFh9vl3QV3VA5O0,724
14
- pycityagent/environment/sim/aoi_service.py,sha256=yM50xhYPLLExwjl5MDlnAuohqJpK0KbIvr_cWLZJEAk,1203
14
+ pycityagent/environment/sim/aoi_service.py,sha256=2UjvUTF4CW4E_L30IRcdwv6t_q1ZdXN3TTLOKSOaaXE,1230
15
15
  pycityagent/environment/sim/client.py,sha256=MHR7Hhu-Cr7B61d3K_QDpSJh4HrUU9JQf6Cu7_8pdsE,3493
16
- pycityagent/environment/sim/clock_service.py,sha256=YG_A_IA7iJp9rOQE3bCPgppzuzzUwWMCzlxSUdOy088,1326
17
- pycityagent/environment/sim/economy_services.py,sha256=ZggCyAK4Tv5SS881lUBe0WyymKq-0PtdWpe8p_pTDiI,7085
18
- pycityagent/environment/sim/lane_service.py,sha256=6ljWiX_GbZd-a-fEcktDZncxBkraLA2LDE_pVV99uLs,3896
19
- pycityagent/environment/sim/light_service.py,sha256=ezYGcV_PkZ6I-yv48LNEjsytwwwQx-1Qp2QCWXWIhdQ,4215
20
- pycityagent/environment/sim/person_service.py,sha256=nIvOsoBoqOTDYtsiThg07-4ZBgkTUDEbb3dHyOjzyb8,10652
21
- pycityagent/environment/sim/road_service.py,sha256=phKTwTyhc_6Ht2mddEXpdENfl-lRXIVY0CHAlw1yHjI,1264
16
+ pycityagent/environment/sim/clock_service.py,sha256=fgYXacf_-ixhVAn5uKUvqvemBS6A0oQK8JOZukkhXyY,1353
17
+ pycityagent/environment/sim/economy_services.py,sha256=xoc-1_H8JmQwJ24oWRS1fD-hGYtz2I-x6BOkQ4yENzU,7106
18
+ pycityagent/environment/sim/lane_service.py,sha256=N2dUe-3XuqqKLsNXt1k4NN8uV-J_ruo08yhaUd_hwOI,3916
19
+ pycityagent/environment/sim/light_service.py,sha256=KVwt7ii_iLGA7gANZe3n6-4RiiPQt1w9H6ZOoizMI04,4242
20
+ pycityagent/environment/sim/person_service.py,sha256=5r1F2Itn7dKJ2U4hSLovrk5p4qy-2n77MTAv_OlTIwA,10673
21
+ pycityagent/environment/sim/road_service.py,sha256=bKyn3_me0sGmaJVyF6eNeFbdU-9C1yWsa9L7pieDJzg,1285
22
22
  pycityagent/environment/sim/sim_env.py,sha256=HI1LcS_FotDKQ6vBnx0e49prXSABOfA20aU9KM-ZkCY,4625
23
- pycityagent/environment/sim/social_service.py,sha256=6Iqvq6dz8H2jhLLdtaITc6Js9QnQw-Ylsd5AZgUj3-E,1993
23
+ pycityagent/environment/sim/social_service.py,sha256=9EFJAwVdUuUQkNkFRn9qZRDfD1brh2fqkvasnXUEBhQ,2014
24
24
  pycityagent/environment/simulator.py,sha256=XjcxbyBIbB3Ht9z087z_oWIPAN6pP5Eq1lyf4W5atb8,12502
25
25
  pycityagent/environment/utils/__init__.py,sha256=1m4Q1EfGvNpUsa1bgQzzCyWhfkpElnskNImjjFD3Znc,237
26
26
  pycityagent/environment/utils/base64.py,sha256=hoREzQo3FXMN79pqQLO2jgsDEvudciomyKii7MWljAM,374
@@ -29,7 +29,7 @@ pycityagent/environment/utils/geojson.py,sha256=LVHAdEhnZM8d0BoUnuPiIL_gaeXBIIgl
29
29
  pycityagent/environment/utils/grpc.py,sha256=6EJwKXXktIWb1NcUiJzIRmfrY0S03QAXXGcCDHqAT00,1998
30
30
  pycityagent/environment/utils/map_utils.py,sha256=lYOEoCFFK6-e9N5txLMMq4HUlxMqc8Uw1YrGW5oJmgg,5749
31
31
  pycityagent/environment/utils/port.py,sha256=3OM6kSUt3PxvDUOlgyiendBtETaWU8Mzk_8H0TzTmYg,295
32
- pycityagent/environment/utils/protobuf.py,sha256=0jBvK_s96y_n7tuMbG22TOtQmg71SGV4ONDy2IGsU9o,1148
32
+ pycityagent/environment/utils/protobuf.py,sha256=0BsM_G7x2B_6DMIBHe9bjVuQDOXUytNRQ03g9e05F3c,1170
33
33
  pycityagent/llm/__init__.py,sha256=7klKEmCcDWJIu-F4DoAukSuKfDbLhdczrSIhpwow-sY,145
34
34
  pycityagent/llm/embedding.py,sha256=2psX_EK67oPlYe77g43EYUYams4M9AiJqxpHTFHG0n8,4253
35
35
  pycityagent/llm/llm.py,sha256=vJaaGqVuyV-GlBxrnvGKZnMDlxeTT_sGUTdxz5tYwEE,15141
@@ -38,19 +38,20 @@ pycityagent/llm/utils.py,sha256=hoNPhvomb1u6lhFX0GctFipw74hVKb7bvUBDqwBzBYw,160
38
38
  pycityagent/memory/__init__.py,sha256=Hs2NhYpIG-lvpwPWwj4DydB1sxtjz7cuA4iDAzCXnjI,243
39
39
  pycityagent/memory/const.py,sha256=6zpJPJXWoH9-yf4RARYYff586agCoud9BRn7sPERB1g,932
40
40
  pycityagent/memory/memory.py,sha256=vJxHOI74aJDGZPFu2LbBr02ASfOYpig66fto6Gjr-6Q,18191
41
- pycityagent/memory/memory_base.py,sha256=euKZRCs4dbcKxjlZzpLCTnH066DAtRjj5g1JFKD40qQ,5633
42
- pycityagent/memory/profile.py,sha256=s4LnxSPGSjIGZXHXkkd8mMa6uYYZrytgyQdWjcaqGf4,5182
43
- pycityagent/memory/self_define.py,sha256=poPiexNhOLq_iTgK8s4mK_xoL_DAAcB8kMvInj7iE5E,5179
44
- pycityagent/memory/state.py,sha256=5W0c1yJ-aaPpE74B2LEcw3Ygpm77tyooHv8NylyrozE,5113
45
- pycityagent/memory/utils.py,sha256=wLNlNlZ-AY9VB8kbUIy0UQSYh26FOQABbhmKQkit5o8,850
41
+ pycityagent/memory/memory_base.py,sha256=QG_j3BxZvkadFEeE3uBR_kjl_xcXD1aHUVs8GEF3d6w,5654
42
+ pycityagent/memory/profile.py,sha256=q8ZS9IBmHCg_X1GONUvXK85P6tCepTKQgXKuvuXYNXw,5203
43
+ pycityagent/memory/self_define.py,sha256=vpZ6CIxR2grNXEIOScdpsSc59FBg0mOKelwQuTElbtQ,5200
44
+ pycityagent/memory/state.py,sha256=TYItiyDtehMEQaSBN7PpNrnNxdDM5jGppr9R9Ufv3kA,5134
45
+ pycityagent/memory/utils.py,sha256=oJWLdPeJy_jcdKcDTo9JAH9kDZhqjoQhhv_zT9qWC0w,877
46
46
  pycityagent/message/__init__.py,sha256=TCjazxqb5DVwbTu1fF0sNvaH_EPXVuj2XQ0p6W-QCLU,55
47
47
  pycityagent/message/messager.py,sha256=W_OVlNGcreHSBf6v-DrEnfNCXExB78ySr0w26MSncfU,2541
48
48
  pycityagent/metrics/__init__.py,sha256=X08PaBbGVAd7_PRGLREXWxaqm7nS82WBQpD1zvQzcqc,128
49
49
  pycityagent/metrics/mlflow_client.py,sha256=g_tHxWkWTDijtbGL74-HmiYzWVKb1y8-w12QrY9jL30,4449
50
50
  pycityagent/metrics/utils/const.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
- pycityagent/simulation/__init__.py,sha256=jYaqaNpzM5M_e_ykISS_M-mIyYdzJXJWhgpfBpA6l5k,111
52
- pycityagent/simulation/agentgroup.py,sha256=6p8-OP2x_syaQ1pWLgll0LHs823OHnappuY-8XzL_LU,13383
53
- pycityagent/simulation/simulation.py,sha256=pxFdaNMLdJMcpW8gnOcxjfbz4gkpcvWsTR0rNP8rE9k,21675
51
+ pycityagent/simulation/__init__.py,sha256=P5czbcg2d8S0nbbnsQXFIhwzO4CennAhZM8OmKvAeYw,194
52
+ pycityagent/simulation/agentgroup.py,sha256=5p68wNoEaog4nDym3xsCTporBWmxNiQ1crN3mbOHFsE,19788
53
+ pycityagent/simulation/simulation.py,sha256=7Go_RkpkC_DuBWW21JPqlV2yXY754RqSkqzM0vTdteU,23008
54
+ pycityagent/simulation/storage/pg.py,sha256=Ws04mUgRcbbvWi_eQm3PXYa6w7AQUbDPWhSU7HFtsD8,6026
54
55
  pycityagent/survey/__init__.py,sha256=rxwou8U9KeFSP7rMzXtmtp2fVFZxK4Trzi-psx9LPIs,153
55
56
  pycityagent/survey/manager.py,sha256=S5IkwTdelsdtZETChRcfCEczzwSrry_Fly9MY4s3rbk,1681
56
57
  pycityagent/survey/models.py,sha256=YE50UUt5qJ0O_lIUsSY6XFCGUTkJVNu_L1gAhaCJ2fs,3546
@@ -59,14 +60,15 @@ pycityagent/utils/avro_schema.py,sha256=DHM3bOo8m0dJf8oSwyOWzVeXrH6OERmzA_a5vS4S
59
60
  pycityagent/utils/decorators.py,sha256=Gk3r41hfk6awui40tbwpq3C7wC7jHaRmLRlcJFlLQCE,3160
60
61
  pycityagent/utils/parsers/__init__.py,sha256=AN2xgiPxszWK4rpX7zrqRsqNwfGF3WnCA5-PFTvbaKk,281
61
62
  pycityagent/utils/parsers/code_block_parser.py,sha256=Cs2Z_hm9VfNCpPPll1TwteaJF-HAQPs-3RApsOekFm4,1173
62
- pycityagent/utils/parsers/json_parser.py,sha256=FZ3XN1g8z4Dr2TFraUOoah1oQcze4fPd2m01hHoX0Mo,2917
63
+ pycityagent/utils/parsers/json_parser.py,sha256=tjwyPluYfkWgsvLi0hzfJwFhO3L6yQfZMKza20HaGrY,2911
63
64
  pycityagent/utils/parsers/parser_base.py,sha256=KBKO4zLZPNdGjPAGqIus8LseZ8W3Tlt2y0QxqeCd25Q,1713
65
+ pycityagent/utils/pg_query.py,sha256=h5158xcrxjUTR0nKwAaG1neFfTHPbN5guLmaXpC8yvs,1918
64
66
  pycityagent/utils/survey_util.py,sha256=Be9nptmu2JtesFNemPgORh_2GsN7rcDYGQS9Zfvc5OI,2169
65
67
  pycityagent/workflow/__init__.py,sha256=QNkUV-9mACMrR8c0cSKna2gC1mMZdxXbxWzjE-Uods0,621
66
- pycityagent/workflow/block.py,sha256=WkE2On97DCZS_9n8aIgT8wxv9Oaff4Fdf2tLqbKfMtE,6010
68
+ pycityagent/workflow/block.py,sha256=l-z9iJo9_USZQRyj4TLMfihK0-tnNDG0a6jVk9WhG0o,6048
67
69
  pycityagent/workflow/prompt.py,sha256=6jI0Rq54JLv3-IXqZLYug62vse10wTI83xvf4ZX42nk,2929
68
- pycityagent/workflow/tool.py,sha256=SGY18lT71hBLKagopirFbxRjPY_387Dobo9SUwjHIn0,8215
70
+ pycityagent/workflow/tool.py,sha256=xADxhNgVsjNiMxlhdwn3xGUstFOkLEG8P67ez8VmwSI,8555
69
71
  pycityagent/workflow/trigger.py,sha256=Df-MOBEDWBbM-v0dFLQLXteLsipymT4n8vqexmK2GiQ,5643
70
- pycityagent-2.0.0a20.dist-info/METADATA,sha256=aygfImVFM4jG0nXVuunu5LZDNi4JyikBULFce0WGWeM,7848
71
- pycityagent-2.0.0a20.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
72
- pycityagent-2.0.0a20.dist-info/RECORD,,
72
+ pycityagent-2.0.0a22.dist-info/METADATA,sha256=s_gC55n1d1ZUyt1kRcYhl7h9Ymp8BQQKXZHrg93V8sg,7848
73
+ pycityagent-2.0.0a22.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
74
+ pycityagent-2.0.0a22.dist-info/RECORD,,