pycityagent 2.0.0a93__cp312-cp312-macosx_11_0_arm64.whl → 2.0.0a95__cp312-cp312-macosx_11_0_arm64.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/agent/agent.py +5 -5
- pycityagent/agent/agent_base.py +1 -2
- pycityagent/cityagent/__init__.py +6 -5
- pycityagent/cityagent/bankagent.py +2 -2
- pycityagent/cityagent/blocks/__init__.py +4 -4
- pycityagent/cityagent/blocks/cognition_block.py +7 -4
- pycityagent/cityagent/blocks/economy_block.py +227 -135
- pycityagent/cityagent/blocks/mobility_block.py +70 -27
- pycityagent/cityagent/blocks/needs_block.py +11 -12
- pycityagent/cityagent/blocks/other_block.py +2 -2
- pycityagent/cityagent/blocks/plan_block.py +22 -24
- pycityagent/cityagent/blocks/social_block.py +15 -17
- pycityagent/cityagent/blocks/utils.py +3 -2
- pycityagent/cityagent/firmagent.py +1 -1
- pycityagent/cityagent/governmentagent.py +1 -1
- pycityagent/cityagent/initial.py +1 -1
- pycityagent/cityagent/memory_config.py +0 -1
- pycityagent/cityagent/message_intercept.py +7 -8
- pycityagent/cityagent/nbsagent.py +1 -1
- pycityagent/cityagent/societyagent.py +1 -2
- pycityagent/configs/__init__.py +18 -0
- pycityagent/configs/exp_config.py +202 -0
- pycityagent/configs/sim_config.py +251 -0
- pycityagent/configs/utils.py +17 -0
- pycityagent/environment/__init__.py +2 -0
- pycityagent/{economy → environment/economy}/econ_client.py +14 -32
- pycityagent/environment/sim/sim_env.py +17 -24
- pycityagent/environment/simulator.py +36 -113
- pycityagent/llm/__init__.py +1 -2
- pycityagent/llm/llm.py +60 -166
- pycityagent/memory/memory.py +13 -12
- pycityagent/message/message_interceptor.py +5 -4
- pycityagent/message/messager.py +3 -5
- pycityagent/metrics/__init__.py +1 -1
- pycityagent/metrics/mlflow_client.py +20 -17
- pycityagent/pycityagent-sim +0 -0
- pycityagent/simulation/agentgroup.py +17 -19
- pycityagent/simulation/simulation.py +157 -210
- pycityagent/survey/manager.py +0 -2
- pycityagent/utils/__init__.py +3 -0
- pycityagent/utils/config_const.py +20 -0
- pycityagent/workflow/__init__.py +1 -2
- pycityagent/workflow/block.py +0 -3
- {pycityagent-2.0.0a93.dist-info → pycityagent-2.0.0a95.dist-info}/METADATA +7 -24
- {pycityagent-2.0.0a93.dist-info → pycityagent-2.0.0a95.dist-info}/RECORD +50 -46
- pycityagent/llm/llmconfig.py +0 -18
- /pycityagent/{economy → environment/economy}/__init__.py +0 -0
- {pycityagent-2.0.0a93.dist-info → pycityagent-2.0.0a95.dist-info}/LICENSE +0 -0
- {pycityagent-2.0.0a93.dist-info → pycityagent-2.0.0a95.dist-info}/WHEEL +0 -0
- {pycityagent-2.0.0a93.dist-info → pycityagent-2.0.0a95.dist-info}/entry_points.txt +0 -0
- {pycityagent-2.0.0a93.dist-info → pycityagent-2.0.0a95.dist-info}/top_level.txt +0 -0
@@ -1,29 +1,27 @@
|
|
1
|
+
import asyncio
|
1
2
|
import json
|
3
|
+
import logging
|
4
|
+
import numbers
|
5
|
+
import pickle as pkl
|
2
6
|
import random
|
3
|
-
from pycityagent.llm.llm import LLM
|
4
|
-
from pycityagent.workflow.block import Block
|
5
|
-
from pycityagent.memory import Memory
|
6
|
-
import pycityproto.city.economy.v2.economy_pb2 as economyv2
|
7
7
|
|
8
|
-
|
8
|
+
import numpy as np
|
9
|
+
import pycityproto.city.economy.v2.economy_pb2 as economyv2
|
9
10
|
|
10
|
-
from .
|
11
|
+
from pycityagent.environment import EconomyClient
|
11
12
|
from pycityagent.environment.simulator import Simulator
|
12
13
|
from pycityagent.llm import LLM
|
14
|
+
from pycityagent.llm.llm import LLM
|
13
15
|
from pycityagent.memory import Memory
|
14
16
|
from pycityagent.workflow import Block
|
15
|
-
import
|
16
|
-
import logging
|
17
|
-
logger = logging.getLogger("pycityagent")
|
18
|
-
import pickle as pkl
|
19
|
-
|
17
|
+
from pycityagent.workflow.block import Block
|
20
18
|
from pycityagent.workflow.prompt import FormatPrompt
|
21
|
-
|
22
|
-
from
|
19
|
+
|
20
|
+
from .dispatcher import BlockDispatcher
|
23
21
|
from .utils import *
|
24
|
-
import
|
25
|
-
|
26
|
-
|
22
|
+
from .utils import TIME_ESTIMATE_PROMPT, clean_json_response
|
23
|
+
|
24
|
+
logger = logging.getLogger("pycityagent")
|
27
25
|
|
28
26
|
def softmax(x, gamma=1.0):
|
29
27
|
if not isinstance(x, np.ndarray):
|
@@ -32,157 +30,217 @@ def softmax(x, gamma=1.0):
|
|
32
30
|
e_x = np.exp(x - np.max(x))
|
33
31
|
return e_x / e_x.sum(axis=-1, keepdims=True)
|
34
32
|
|
33
|
+
|
35
34
|
class WorkBlock(Block):
|
36
35
|
"""WorkPlace Block"""
|
36
|
+
|
37
37
|
def __init__(self, llm: LLM, memory: Memory, simulator: Simulator):
|
38
38
|
super().__init__("WorkBlock", llm=llm, memory=memory, simulator=simulator)
|
39
39
|
self.description = "Do work related tasks"
|
40
40
|
self.guidance_prompt = FormatPrompt(template=TIME_ESTIMATE_PROMPT)
|
41
|
+
|
41
42
|
async def forward(self, step, context):
|
42
43
|
self.guidance_prompt.format(
|
43
|
-
plan=context[
|
44
|
-
intention=step[
|
44
|
+
plan=context["plan"],
|
45
|
+
intention=step["intention"],
|
45
46
|
emotion_types=await self.memory.status.get("emotion_types"),
|
46
47
|
)
|
47
|
-
result = await self.llm.atext_request(self.guidance_prompt.to_dialog())
|
48
|
+
result = await self.llm.atext_request(self.guidance_prompt.to_dialog(), response_format={"type": "json_object"})
|
48
49
|
result = clean_json_response(result)
|
49
50
|
try:
|
50
51
|
result = json.loads(result)
|
51
|
-
time = result[
|
52
|
+
time = result["time"]
|
52
53
|
start_time = await self.simulator.get_time(format_time=True)
|
53
|
-
await self.memory.status.update(
|
54
|
+
await self.memory.status.update(
|
55
|
+
"working_experience",
|
56
|
+
[
|
57
|
+
f"Start from {start_time}, worked {time} minutes on {step['intention']}"
|
58
|
+
],
|
59
|
+
mode="merge",
|
60
|
+
)
|
54
61
|
work_hour_finish = await self.memory.status.get("work_hour_finish")
|
55
|
-
work_hour_finish += float(time/60)
|
56
|
-
node_id = await self.memory.stream.add_economy(
|
62
|
+
work_hour_finish += float(time / 60)
|
63
|
+
node_id = await self.memory.stream.add_economy(
|
64
|
+
description=f"I worked {time} minutes on {step['intention']}"
|
65
|
+
)
|
57
66
|
await self.memory.status.update("work_hour_finish", work_hour_finish)
|
58
67
|
return {
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
68
|
+
"success": True,
|
69
|
+
"evaluation": f'work: {step["intention"]}',
|
70
|
+
"consumed_time": time,
|
71
|
+
"node_id": node_id,
|
63
72
|
}
|
64
73
|
except Exception as e:
|
65
74
|
logger.warning(f"解析时间评估响应时发生错误: {str(e)}, 原始结果: {result}")
|
66
|
-
time = random.randint(1, 5)*60
|
75
|
+
time = random.randint(1, 5) * 60
|
67
76
|
start_time = await self.simulator.get_time(format_time=True)
|
68
|
-
await self.memory.status.update(
|
77
|
+
await self.memory.status.update(
|
78
|
+
"working_experience",
|
79
|
+
[
|
80
|
+
f"Start from {start_time}, worked {time} minutes on {step['intention']}"
|
81
|
+
],
|
82
|
+
mode="merge",
|
83
|
+
)
|
69
84
|
work_hour_finish = await self.memory.status.get("work_hour_finish")
|
70
|
-
node_id = await self.memory.stream.add_economy(
|
71
|
-
|
85
|
+
node_id = await self.memory.stream.add_economy(
|
86
|
+
description=f"I worked {time} minutes on {step['intention']}"
|
87
|
+
)
|
88
|
+
work_hour_finish += float(time / 60)
|
72
89
|
await self.memory.status.update("work_hour_finish", work_hour_finish)
|
73
90
|
return {
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
91
|
+
"success": True,
|
92
|
+
"evaluation": f'work: {step["intention"]}',
|
93
|
+
"consumed_time": time,
|
94
|
+
"node_id": node_id,
|
78
95
|
}
|
79
|
-
|
96
|
+
|
97
|
+
|
80
98
|
class ConsumptionBlock(Block):
|
81
99
|
"""
|
82
100
|
determine the consumption amount, and items
|
83
101
|
"""
|
84
|
-
|
85
|
-
|
102
|
+
|
103
|
+
def __init__(
|
104
|
+
self,
|
105
|
+
llm: LLM,
|
106
|
+
memory: Memory,
|
107
|
+
simulator: Simulator,
|
108
|
+
economy_client: EconomyClient,
|
109
|
+
):
|
110
|
+
super().__init__(
|
111
|
+
"ConsumptionBlock", llm=llm, memory=memory, simulator=simulator
|
112
|
+
)
|
86
113
|
self.economy_client = economy_client
|
87
114
|
self.forward_times = 0
|
88
115
|
self.description = "Used to determine the consumption amount, and items"
|
89
116
|
|
90
117
|
async def forward(self, step, context):
|
91
118
|
self.forward_times += 1
|
92
|
-
agent_id = await self.memory.status.get("id")
|
119
|
+
agent_id = await self.memory.status.get("id") # agent_id
|
93
120
|
firms_id = await self.economy_client.get_org_entity_ids(economyv2.ORG_TYPE_FIRM)
|
94
121
|
intention = step["intention"]
|
95
|
-
month_consumption = await self.memory.status.get(
|
96
|
-
consumption_currency = await self.economy_client.get(agent_id,
|
122
|
+
month_consumption = await self.memory.status.get("to_consumption_currency")
|
123
|
+
consumption_currency = await self.economy_client.get(agent_id, "consumption")
|
97
124
|
if consumption_currency >= month_consumption:
|
98
|
-
node_id = await self.memory.stream.add_economy(
|
125
|
+
node_id = await self.memory.stream.add_economy(
|
126
|
+
description=f"I have passed the monthly consumption limit, so I will not consume."
|
127
|
+
)
|
99
128
|
return {
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
129
|
+
"success": False,
|
130
|
+
"evaluation": f"I have passed the monthly consumption limit, so I will not consume.",
|
131
|
+
"consumed_time": 0,
|
132
|
+
"node_id": node_id,
|
104
133
|
}
|
105
|
-
consumption = min(
|
134
|
+
consumption = min(
|
135
|
+
month_consumption / 1, month_consumption - consumption_currency
|
136
|
+
)
|
106
137
|
prices = []
|
107
138
|
for this_firm_id in firms_id:
|
108
|
-
price = await self.economy_client.get(this_firm_id,
|
139
|
+
price = await self.economy_client.get(this_firm_id, "price")
|
109
140
|
prices.append(price)
|
110
|
-
consumption_each_firm = consumption*softmax(prices, gamma=-0.01)
|
141
|
+
consumption_each_firm = consumption * softmax(prices, gamma=-0.01)
|
111
142
|
demand_each_firm = []
|
112
143
|
for i in range(len(firms_id)):
|
113
|
-
demand_each_firm.append(int(consumption_each_firm[i]//prices[i]))
|
114
|
-
real_consumption = await self.economy_client.calculate_consumption(
|
115
|
-
|
144
|
+
demand_each_firm.append(int(consumption_each_firm[i] // prices[i]))
|
145
|
+
real_consumption = await self.economy_client.calculate_consumption(
|
146
|
+
firms_id, agent_id, demand_each_firm
|
147
|
+
)
|
148
|
+
node_id = await self.memory.stream.add_economy(
|
149
|
+
description=f"I bought some goods, and spent {real_consumption:.1f} on {intention}"
|
150
|
+
)
|
116
151
|
evaluation = {
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
152
|
+
"success": True,
|
153
|
+
"evaluation": f"I bought some goods, and spent {real_consumption:.1f} on {intention}",
|
154
|
+
"consumed_time": 20,
|
155
|
+
"node_id": node_id,
|
121
156
|
}
|
122
157
|
return evaluation
|
123
|
-
|
158
|
+
|
159
|
+
|
124
160
|
class EconomyNoneBlock(Block):
|
125
161
|
"""
|
126
162
|
Do anything else
|
127
163
|
NoneBlock
|
128
164
|
"""
|
165
|
+
|
129
166
|
def __init__(self, llm: LLM, memory: Memory):
|
130
167
|
super().__init__("NoneBlock", llm=llm, memory=memory)
|
131
168
|
self.description = "Do anything else"
|
132
169
|
|
133
170
|
async def forward(self, step, context):
|
134
|
-
node_id = await self.memory.stream.add_economy(
|
171
|
+
node_id = await self.memory.stream.add_economy(
|
172
|
+
description=f"I {step['intention']}"
|
173
|
+
)
|
135
174
|
return {
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
175
|
+
"success": True,
|
176
|
+
"evaluation": f'Finished{step["intention"]}',
|
177
|
+
"consumed_time": 0,
|
178
|
+
"node_id": node_id,
|
140
179
|
}
|
141
180
|
|
181
|
+
|
142
182
|
class EconomyBlock(Block):
|
143
183
|
work_block: WorkBlock
|
144
184
|
consumption_block: ConsumptionBlock
|
145
185
|
none_block: EconomyNoneBlock
|
146
186
|
|
147
|
-
def __init__(
|
187
|
+
def __init__(
|
188
|
+
self,
|
189
|
+
llm: LLM,
|
190
|
+
memory: Memory,
|
191
|
+
simulator: Simulator,
|
192
|
+
economy_client: EconomyClient,
|
193
|
+
):
|
148
194
|
super().__init__("EconomyBlock", llm=llm, memory=memory, simulator=simulator)
|
149
195
|
self.economy_client = economy_client
|
150
196
|
self.work_block = WorkBlock(llm, memory, simulator)
|
151
|
-
self.consumption_block = ConsumptionBlock(
|
197
|
+
self.consumption_block = ConsumptionBlock(
|
198
|
+
llm, memory, simulator, economy_client
|
199
|
+
)
|
152
200
|
self.none_block = EconomyNoneBlock(llm, memory)
|
153
201
|
self.trigger_time = 0
|
154
202
|
self.token_consumption = 0
|
155
203
|
self.dispatcher = BlockDispatcher(llm)
|
156
|
-
self.dispatcher.register_blocks(
|
204
|
+
self.dispatcher.register_blocks(
|
205
|
+
[self.work_block, self.consumption_block, self.none_block]
|
206
|
+
)
|
157
207
|
|
158
|
-
async def forward(self, step, context):
|
208
|
+
async def forward(self, step, context):
|
159
209
|
self.trigger_time += 1
|
160
210
|
selected_block = await self.dispatcher.dispatch(step)
|
161
|
-
result = await selected_block.forward(step, context)
|
211
|
+
result = await selected_block.forward(step, context) # type: ignore
|
162
212
|
return result
|
163
|
-
|
213
|
+
|
214
|
+
|
164
215
|
class MonthPlanBlock(Block):
|
165
216
|
"""Monthly Planning"""
|
217
|
+
|
166
218
|
configurable_fields = [
|
167
219
|
"UBI",
|
168
220
|
"num_labor_hours",
|
169
221
|
"productivity_per_labor",
|
170
|
-
"time_diff"
|
222
|
+
"time_diff",
|
171
223
|
]
|
172
224
|
default_values = {
|
173
225
|
"UBI": 0,
|
174
226
|
"num_labor_hours": 168,
|
175
227
|
"productivity_per_labor": 1,
|
176
|
-
"time_diff": 30 * 24 * 60 * 60
|
228
|
+
"time_diff": 30 * 24 * 60 * 60,
|
177
229
|
}
|
178
230
|
fields_description = {
|
179
231
|
"UBI": "Universal Basic Income",
|
180
232
|
"num_labor_hours": "Number of labor hours per month",
|
181
233
|
"productivity_per_labor": "Productivity per labor hour",
|
182
|
-
"time_diff": "Time difference between two triggers"
|
234
|
+
"time_diff": "Time difference between two triggers",
|
183
235
|
}
|
184
236
|
|
185
|
-
def __init__(
|
237
|
+
def __init__(
|
238
|
+
self,
|
239
|
+
llm: LLM,
|
240
|
+
memory: Memory,
|
241
|
+
simulator: Simulator,
|
242
|
+
economy_client: EconomyClient,
|
243
|
+
):
|
186
244
|
super().__init__("MonthPlanBlock", llm=llm, memory=memory, simulator=simulator)
|
187
245
|
self.economy_client = economy_client
|
188
246
|
self.llm_error = 0
|
@@ -194,57 +252,66 @@ class MonthPlanBlock(Block):
|
|
194
252
|
self.num_labor_hours = 168
|
195
253
|
self.productivity_per_labor = 1
|
196
254
|
self.time_diff = 30 * 24 * 60 * 60
|
197
|
-
|
255
|
+
|
198
256
|
async def month_trigger(self):
|
199
257
|
now_time = await self.simulator.get_time()
|
200
|
-
if
|
258
|
+
if (
|
259
|
+
self.last_time_trigger is None
|
260
|
+
or now_time - self.last_time_trigger >= self.time_diff
|
261
|
+
):
|
201
262
|
self.last_time_trigger = now_time
|
202
263
|
return True
|
203
264
|
return False
|
204
|
-
|
265
|
+
|
205
266
|
async def forward(self):
|
206
267
|
if await self.month_trigger():
|
207
268
|
agent_id = await self.memory.status.get("id")
|
208
|
-
firms_id = await self.economy_client.get_org_entity_ids(
|
209
|
-
|
210
|
-
|
269
|
+
firms_id = await self.economy_client.get_org_entity_ids(
|
270
|
+
economyv2.ORG_TYPE_FIRM
|
271
|
+
)
|
272
|
+
firm_id = await self.memory.status.get("firm_id")
|
273
|
+
bank_id = await self.economy_client.get_org_entity_ids(
|
274
|
+
economyv2.ORG_TYPE_BANK
|
275
|
+
)
|
211
276
|
bank_id = bank_id[0]
|
212
|
-
name = await self.memory.status.get(
|
213
|
-
age = await self.memory.status.get(
|
214
|
-
city = await self.memory.status.get(
|
215
|
-
job = await self.memory.status.get(
|
216
|
-
skill = await self.economy_client.get(agent_id,
|
217
|
-
consumption = await self.economy_client.get(agent_id,
|
218
|
-
tax_paid = await self.memory.status.get(
|
277
|
+
name = await self.memory.status.get("name")
|
278
|
+
age = await self.memory.status.get("age")
|
279
|
+
city = await self.memory.status.get("city")
|
280
|
+
job = await self.memory.status.get("occupation")
|
281
|
+
skill = await self.economy_client.get(agent_id, "skill")
|
282
|
+
consumption = await self.economy_client.get(agent_id, "consumption")
|
283
|
+
tax_paid = await self.memory.status.get("tax_paid")
|
219
284
|
prices = []
|
220
285
|
for this_firm_id in firms_id:
|
221
|
-
price = await self.economy_client.get(this_firm_id,
|
286
|
+
price = await self.economy_client.get(this_firm_id, "price")
|
222
287
|
prices.append(price)
|
223
288
|
price = np.mean(prices)
|
224
|
-
wealth = await self.economy_client.get(agent_id,
|
225
|
-
interest_rate = await self.economy_client.get(bank_id,
|
226
|
-
|
227
|
-
problem_prompt = f
|
289
|
+
wealth = await self.economy_client.get(agent_id, "currency")
|
290
|
+
interest_rate = await self.economy_client.get(bank_id, "interest_rate")
|
291
|
+
|
292
|
+
problem_prompt = f"""
|
228
293
|
You're {name}, a {age}-year-old individual living in {city}. As with all Americans, a portion of your monthly income is taxed by the federal government. This taxation system is tiered, income is taxed cumulatively within defined brackets, combined with a redistributive policy: after collection, the government evenly redistributes the tax revenue back to all citizens, irrespective of their earnings.
|
229
|
-
|
230
|
-
job_prompt = f
|
294
|
+
"""
|
295
|
+
job_prompt = f"""
|
231
296
|
In the previous month, you worked as a(an) {job}. If you continue working this month, your expected hourly income will be ${skill:.2f}.
|
232
|
-
|
233
|
-
consumption_propensity = await self.memory.status.get(
|
297
|
+
"""
|
298
|
+
consumption_propensity = await self.memory.status.get(
|
299
|
+
"consumption_propensity"
|
300
|
+
)
|
234
301
|
if (consumption <= 0) and (consumption_propensity > 0):
|
235
|
-
consumption_prompt = f
|
302
|
+
consumption_prompt = f"""
|
236
303
|
Besides, you had no consumption due to shortage of goods.
|
237
|
-
|
304
|
+
"""
|
238
305
|
else:
|
239
|
-
consumption_prompt = f
|
306
|
+
consumption_prompt = f"""
|
240
307
|
Besides, your consumption was ${consumption:.2f}.
|
241
|
-
|
242
|
-
tax_prompt = f
|
308
|
+
"""
|
309
|
+
tax_prompt = f"""Your tax deduction amounted to ${tax_paid:.2f}, and the government uses the tax revenue to provide social services to all citizens."""
|
243
310
|
if self.UBI and self.forward_times >= 96:
|
244
|
-
tax_prompt = f
|
245
|
-
price_prompt = f
|
311
|
+
tax_prompt = f"{tax_prompt} Specifically, the government directly provides ${self.UBI} per capita in each month."
|
312
|
+
price_prompt = f"""Meanwhile, in the consumption market, the average price of essential goods is now at ${price:.2f}."""
|
246
313
|
job_prompt = prettify_document(job_prompt)
|
247
|
-
obs_prompt = f
|
314
|
+
obs_prompt = f"""
|
248
315
|
{problem_prompt} {job_prompt} {consumption_prompt} {tax_prompt} {price_prompt}
|
249
316
|
Your current savings account balance is ${wealth:.2f}. Interest rates, as set by your bank, stand at {interest_rate*100:.2f}%.
|
250
317
|
Your goal is to maximize your utility by deciding how much to work and how much to consume. Your utility is determined by your consumption, income, saving, social service recieved and leisure time. You will spend the time you do not work on leisure activities.
|
@@ -254,47 +321,68 @@ class MonthPlanBlock(Block):
|
|
254
321
|
'consumption': a value between 0 and 1, indicating the proportion of all your savings and income you intend to spend on essential goods
|
255
322
|
}}
|
256
323
|
Any other output words are NOT allowed.
|
257
|
-
|
324
|
+
"""
|
258
325
|
obs_prompt = prettify_document(obs_prompt)
|
259
326
|
try:
|
260
|
-
await self.memory.status.update(
|
261
|
-
|
327
|
+
await self.memory.status.update(
|
328
|
+
"dialog_queue",
|
329
|
+
[{"role": "user", "content": obs_prompt}],
|
330
|
+
mode="merge",
|
331
|
+
)
|
332
|
+
dialog_queue = await self.memory.status.get("dialog_queue")
|
262
333
|
content = await self.llm.atext_request(list(dialog_queue), timeout=300)
|
263
|
-
await self.memory.status.update(
|
334
|
+
await self.memory.status.update(
|
335
|
+
"dialog_queue",
|
336
|
+
[{"role": "assistant", "content": content}],
|
337
|
+
mode="merge",
|
338
|
+
)
|
264
339
|
propensity_dict = extract_dict_from_string(content)[0]
|
265
|
-
work_propensity, consumption_propensity =
|
266
|
-
|
267
|
-
|
268
|
-
|
340
|
+
work_propensity, consumption_propensity = (
|
341
|
+
propensity_dict["work"],
|
342
|
+
propensity_dict["consumption"],
|
343
|
+
)
|
344
|
+
if isinstance(work_propensity, numbers.Number) and isinstance(
|
345
|
+
consumption_propensity, numbers.Number
|
346
|
+
):
|
347
|
+
await self.memory.status.update("work_propensity", work_propensity)
|
348
|
+
await self.memory.status.update(
|
349
|
+
"consumption_propensity", consumption_propensity
|
350
|
+
)
|
269
351
|
else:
|
270
352
|
self.llm_error += 1
|
271
353
|
except:
|
272
354
|
self.llm_error += 1
|
273
|
-
|
274
|
-
work_skill = await self.economy_client.get(agent_id,
|
275
|
-
work_propensity = await self.memory.status.get(
|
276
|
-
consumption_propensity = await self.memory.status.get(
|
355
|
+
|
356
|
+
work_skill = await self.economy_client.get(agent_id, "skill")
|
357
|
+
work_propensity = await self.memory.status.get("work_propensity")
|
358
|
+
consumption_propensity = await self.memory.status.get(
|
359
|
+
"consumption_propensity"
|
360
|
+
)
|
277
361
|
work_hours = work_propensity * self.num_labor_hours
|
278
362
|
# income = await self.economy_client.get(agent_id, 'income')
|
279
363
|
income = work_hours * work_skill
|
280
|
-
|
281
|
-
wealth = await self.economy_client.get(agent_id,
|
364
|
+
|
365
|
+
wealth = await self.economy_client.get(agent_id, "currency")
|
282
366
|
wealth += work_hours * work_skill
|
283
|
-
await self.economy_client.update(agent_id,
|
284
|
-
await self.economy_client.add_delta_value(
|
285
|
-
|
367
|
+
await self.economy_client.update(agent_id, "currency", wealth)
|
368
|
+
await self.economy_client.add_delta_value(
|
369
|
+
firm_id, "inventory", int(work_hours * self.productivity_per_labor)
|
370
|
+
)
|
371
|
+
|
286
372
|
if self.UBI and self.forward_times >= 96:
|
287
373
|
income += self.UBI
|
288
374
|
wealth += self.UBI
|
289
375
|
|
290
|
-
await self.memory.status.update(
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
await self.economy_client.update(agent_id,
|
295
|
-
|
376
|
+
await self.memory.status.update(
|
377
|
+
"to_consumption_currency", consumption_propensity * wealth
|
378
|
+
)
|
379
|
+
|
380
|
+
await self.economy_client.update(agent_id, "consumption", 0)
|
381
|
+
await self.economy_client.update(agent_id, "income", income)
|
382
|
+
await self.economy_client.update(agent_id, "currency", wealth)
|
383
|
+
|
296
384
|
if self.forward_times % 3 == 0:
|
297
|
-
obs_prompt = f
|
385
|
+
obs_prompt = f"""
|
298
386
|
{problem_prompt} {job_prompt} {consumption_prompt} {tax_prompt} {price_prompt}
|
299
387
|
Your current savings account balance is ${wealth:.2f}. Interest rates, as set by your bank, stand at {interest_rate*100:.2f}%.
|
300
388
|
Please fill in the following questionnaire:
|
@@ -325,11 +413,13 @@ class MonthPlanBlock(Block):
|
|
325
413
|
Statement 20: I could not get "going".
|
326
414
|
Please response with json format with keys being numbers 1-20 and values being one of "Rarely", "Some", "Occasionally", "Most".
|
327
415
|
Any other output words are NOT allowed.
|
328
|
-
|
416
|
+
"""
|
329
417
|
obs_prompt = prettify_document(obs_prompt)
|
330
|
-
content = await self.llm.atext_request(
|
418
|
+
content = await self.llm.atext_request(
|
419
|
+
[{"role": "user", "content": obs_prompt}], timeout=300
|
420
|
+
)
|
331
421
|
inverse_score_items = [3, 8, 12, 16]
|
332
|
-
category2score = {
|
422
|
+
category2score = {"rarely": 0, "some": 1, "occasionally": 2, "most": 3}
|
333
423
|
try:
|
334
424
|
content = extract_dict_from_string(content)[0]
|
335
425
|
for k in content:
|
@@ -338,18 +428,20 @@ class MonthPlanBlock(Block):
|
|
338
428
|
else:
|
339
429
|
content[k] = category2score[content[k].lower()]
|
340
430
|
depression = sum(list(content.values()))
|
341
|
-
await self.memory.status.update(
|
431
|
+
await self.memory.status.update("depression", depression)
|
342
432
|
except:
|
343
433
|
self.llm_error += 1
|
344
434
|
|
345
435
|
if self.UBI and self.forward_times >= 96 and self.forward_times % 12 == 0:
|
346
|
-
obs_prompt = f
|
436
|
+
obs_prompt = f"""
|
347
437
|
{problem_prompt} {job_prompt} {consumption_prompt} {tax_prompt} {price_prompt}
|
348
438
|
Your current savings account balance is ${wealth:.2f}. Interest rates, as set by your bank, stand at {interest_rate*100:.2f}%.
|
349
439
|
What's your opinion on the UBI policy, including the advantages and disadvantages?
|
350
|
-
|
440
|
+
"""
|
351
441
|
obs_prompt = prettify_document(obs_prompt)
|
352
|
-
content = await self.llm.atext_request(
|
353
|
-
|
442
|
+
content = await self.llm.atext_request(
|
443
|
+
[{"role": "user", "content": obs_prompt}], timeout=300
|
444
|
+
)
|
445
|
+
await self.memory.status.update("ubi_opinion", [content], mode="merge")
|
354
446
|
|
355
|
-
self.forward_times += 1
|
447
|
+
self.forward_times += 1
|