-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstreamlit_app.py
209 lines (173 loc) · 9.64 KB
/
streamlit_app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import streamlit as st
import yaml
import os
from run_simulation import main
import json
from datetime import datetime
import pandas as pd
import glob
from src.web.util import parse_log
from src.util import calculate_accuracy_rate
st.set_page_config(layout="wide")
# Initialize session state
if 'simulation_running' not in st.session_state:
st.session_state.simulation_running = False
if 'current_day' not in st.session_state:
st.session_state.current_day = 1
if 'real_time_data' not in st.session_state:
st.session_state.real_time_data = {}
if 'history_action' not in st.session_state:
st.session_state.history_action = {}
if 'history_prompt' not in st.session_state:
st.session_state.history_prompt = {}
if 'agents' not in st.session_state:
st.session_state.agents = []
# Load default st.session_state.config
with open('configs/config.yaml', 'r') as file:
st.session_state.config = yaml.safe_load(file)
st.title("Student Agent Simulation Dashboard")
# Create two columns for the layout
col1, col2 = st.columns([1, 3])
with col1:
st.header("Configuration")
# Create tabs
load_tab, run_tab = st.tabs(["Load Existing Log", "Run New Simulation"])
with load_tab:
# Get list of log directories
log_dirs = glob.glob('logs/*/')
if log_dirs:
selected_log = st.selectbox(
"Select Log Directory",
options=log_dirs,
format_func=lambda x: x.split('/')[-2]
)
### Load and display selected log###
if st.button("Load Selected Log"):
logs = [log for log in glob.glob(os.path.join(selected_log, '*.log')) if 'Teacher' not in log]
for log in logs:
agent_name = log.split('/')[-1].split('.')[0]
st.session_state.agents.append(agent_name)
with open(log, 'r') as file:
st.session_state.history_prompt[agent_name], st.session_state.history_action[agent_name] = parse_log(file.read())
with open(f'{selected_log}/agents_score.json', 'r') as file:
st.session_state.final_exam_score = json.load(file)
st.session_state.simulation_running = True
st.success(f"Loaded log from {selected_log}")
else:
st.warning("No log directories found")
with run_tab:
# Status value inputs
st.subheader("Status Values")
status_values = {
'loss_mood_study': st.number_input('Loss Mood (Study)', value=st.session_state.config['Status']['loss_mood_study']),
'loss_energy_study': st.number_input('Loss Energy (Study)', value=st.session_state.config['Status']['loss_energy_study']),
'loss_mood_take_courses': st.number_input('Loss Mood (Courses)', value=st.session_state.config['Status']['loss_mood_take_courses']),
'loss_energy_take_courses': st.number_input('Loss Energy (Courses)', value=st.session_state.config['Status']['loss_energy_take_courses']),
'loss_energy_socialize': st.number_input('Loss Energy (Socialize)', value=st.session_state.config['Status']['loss_energy_socialize']),
'add_mood_socialize': st.number_input('Add Mood (Socialize)', value=st.session_state.config['Status']['add_mood_socialize']),
'add_mood_relax': st.number_input('Add Mood (Relax)', value=st.session_state.config['Status']['add_mood_relax']),
'add_energy_sleep': st.number_input('Add Energy (Sleep)', value=st.session_state.config['Status']['add_energy_sleep']),
'add_health_exercise': st.number_input('Add Health (Exercise)', value=st.session_state.config['Status']['add_health_exercise']),
}
# PDF file upload
st.subheader("Upload Study Material")
uploaded_file = st.file_uploader("Choose a PDF file", type="pdf")
### Start real-time simulation ###
if st.button("Start Real-time Simulation"):
pass
# Update st.session_state.config with new values
updated_st.session_state.config = st.session_state.config.copy()
updated_st.session_state.config['Status'].update(status_values)
if uploaded_file:
# Save uploaded PDF
pdf_path = os.path.join('materials', uploaded_file.name)
with open(pdf_path, 'wb') as f:
f.write(uploaded_file.getbuffer())
updated_st.session_state.config['System']['PDF_PATH'] = pdf_path
# Save updated st.session_state.config
with open('st.session_state.configs/st.session_state.config.yaml', 'w') as file:
yaml.dump(updated_st.session_state.config, file)
# Clear previous data
st.session_state.real_time_data = {}
st.session_state.simulation_running = True
st.session_state.current_day = 1
# Start real-time simulation
placeholder = st.empty()
for day in range(1, updated_st.session_state.config['System']['DAYS'] + 1):
# Run simulation for one day
main(grade=False, real_time=True, current_day=day)
# Load the latest results
log_dir = updated_st.session_state.config['System']['LOG_PATH'].format(
date_time=datetime.now().strftime('%Y%m%d_%H%M%S'))
with open(f'{log_dir}/agents_history.json', 'r') as file:
st.session_state.real_time_data = json.load(file)
with col2:
st.header("Simulation Results")
if st.session_state.simulation_running:
# Determine which data to use
if st.session_state.history_action:
# Create a row for navigation controls
nav_col1, nav_col2, nav_col3 = st.columns([1, 10, 1])
# Get max day from actual data
max_day = st.session_state.config['System']['DAYS']
# Initialize selected_day in session state if not exists
if 'selected_day' not in st.session_state:
st.session_state.selected_day = max_day
# Left arrow (previous day)
with nav_col1:
if st.button("←", key="prev_day"):
st.session_state.selected_day = max(1, st.session_state.selected_day - 1)
# Day slider
with nav_col2:
st.session_state.selected_day = st.slider(
"Select Day",
1,
max_day,
st.session_state.selected_day
)
# Right arrow (next day)
with nav_col3:
if st.button("→", key="next_day"):
st.session_state.selected_day = min(max_day, st.session_state.selected_day + 1)
# Create container for results to maintain state
results_container = st.container()
with results_container:
# Display results for selected day
st.subheader(f"Day {st.session_state.selected_day} Results")
# Create columns for each agent
cols = st.columns(len(st.session_state.agents))
for idx, agent_name in enumerate(st.session_state.agents):
with cols[idx]:
# Dummy image (replace with actual agent photos later)
if os.path.exists(f'configs/images/{agent_name}.png'):
st.image(f"configs/images/{agent_name}.png", caption=agent_name)
else:
st.image("https://via.placeholder.com/300", caption=agent_name)
# Display actions and final status
if st.session_state.selected_day in st.session_state.history_action[agent_name]:
actions_data = st.session_state.history_action[agent_name][st.session_state.selected_day]
st.write("**Actions:**")
for action_data in actions_data:
st.write(f"- {action_data['action']}")
st.write("**Status:**")
final_status = actions_data[-1]['status'] # Get the final status from the last action
for status_key, status_value in final_status.items():
st.progress(max(0.0, min(1.0, status_value / 100)),
text=f"{status_key}: {status_value}")
prompt_data = st.session_state.history_prompt[agent_name][st.session_state.selected_day]
st.write("**Thinking Process:**")
text = ""
for prompt in prompt_data:
if 'decide action' in prompt['prompt_name']:
text += prompt['output'] + "\n"
expander = st.expander("Show Thinking Process")
with expander:
st.write(text)
else:
st.warning(f"No data for day {st.session_state.selected_day}")
st.write("-"*40)
st.subheader("Final Exam Score")
for agent, score in st.session_state.final_exam_score.items():
st.write(f"{agent}: {score}")
elif st.session_state.real_time_data:
st.header("Work In Progress")