Skip to content

Commit 8af5077

Browse files
committed
UI improvements
1 parent 8e4233b commit 8af5077

1 file changed

Lines changed: 75 additions & 27 deletions

File tree

agentic/web_ui/gradio_chat.py

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
WS_URL = "ws://127.0.0.1:8000/ws/test"
1515
DEFAULT_AGENT_DIR = Path(__file__).parent.parent
1616
DEFAULT_TESTS_DIR = DEFAULT_AGENT_DIR / "tests"
17+
DEFAULT_AGENT_PATTERN = "libe_agent*.py"
1718

1819
ws_conn = None
1920
message_queue = Queue()
@@ -23,7 +24,9 @@
2324
uvicorn_process = None
2425

2526

26-
def scan_agent_scripts(agent_dir_path):
27+
def scan_agent_scripts(agent_dir_path, pattern=None):
28+
if pattern is None:
29+
pattern = DEFAULT_AGENT_PATTERN
2730
try:
2831
if not agent_dir_path:
2932
return []
@@ -35,7 +38,7 @@ def scan_agent_scripts(agent_dir_path):
3538
print(f"Warning: Agent path is not a directory: {agent_dir_path}")
3639
return []
3740
exclude = {"app.py", "gradio_chat.py", "__init__.py"}
38-
scripts = [f.name for f in sorted(agent_dir.glob("*.py")) if f.name not in exclude]
41+
scripts = [f.name for f in sorted(agent_dir.glob(pattern)) if f.name not in exclude]
3942
return scripts
4043
except Exception as e:
4144
print(f"Error scanning agent scripts: {e}")
@@ -127,16 +130,18 @@ async def _run():
127130

128131
agent_dir_state = gr.State(value=str(DEFAULT_AGENT_DIR))
129132
scripts_dir_state = gr.State(value=str(DEFAULT_TESTS_DIR))
133+
agent_pattern_state = gr.State(value=DEFAULT_AGENT_PATTERN)
130134
settings_visible = gr.State(value=False)
131135

132136
with gr.Column(visible=False) as settings_modal:
133137
with gr.Column(elem_classes="modal-content"):
134138
gr.Markdown("### Settings")
135139
agent_dir_input = gr.Textbox(label="Agent Directory", value=str(DEFAULT_AGENT_DIR))
136-
scripts_dir_input = gr.Textbox(label="Scripts Directory", value=str(DEFAULT_TESTS_DIR))
140+
scripts_dir_input = gr.Textbox(label="Scripts Parent Directory", value=str(DEFAULT_TESTS_DIR))
141+
agent_pattern_input = gr.Textbox(label="Agent Script Pattern", value=DEFAULT_AGENT_PATTERN)
137142
with gr.Row():
138-
apply_settings_btn = gr.Button("Apply", variant="primary", scale=1)
139-
close_settings_btn = gr.Button("Close", scale=1)
143+
apply_settings_btn = gr.Button("Apply", variant="primary", size="sm")
144+
close_settings_btn = gr.Button("Close", size="sm")
140145

141146
with gr.Row():
142147
agent_dropdown = gr.Dropdown(
@@ -148,8 +153,8 @@ async def _run():
148153
label="Scripts Directory", choices=_init_tests,
149154
value=None, allow_custom_value=True, scale=2
150155
)
151-
run_btn = gr.Button("Run", variant="primary", scale=1)
152-
reset_btn = gr.Button("Reset", variant="stop", scale=1)
156+
run_btn = gr.Button("Run", variant="primary")
157+
reset_btn = gr.Button("Reset", variant="stop")
153158

154159
scripts_dict = gr.State(value={})
155160

@@ -167,20 +172,25 @@ async def _run():
167172

168173
def process_messages(scripts_state):
169174
import time
170-
scripts = scripts_state if scripts_state else {}
171-
script_names = list(scripts.keys())
172-
selected_script = script_names[0] if script_names else None
173-
logs = ""
174-
done = False
175-
task_started = False
176-
start_time = time.time()
177-
timeout = 300
175+
try:
176+
scripts = scripts_state if scripts_state else {}
177+
script_names = list(scripts.keys())
178+
selected_script = script_names[0] if script_names else None
179+
logs = ""
180+
done = False
181+
task_started = False
182+
start_time = time.time()
183+
timeout = 300
178184

179-
while not output_queue.empty():
180-
try:
181-
output_queue.get_nowait()
182-
except Empty:
183-
break
185+
while not output_queue.empty():
186+
try:
187+
output_queue.get_nowait()
188+
except Empty:
189+
break
190+
except Exception as e:
191+
error_msg = f"ERROR in process_messages: {str(e)}"
192+
print(error_msg)
193+
return error_msg, {}, gr.update(choices=[], value=None), ""
184194

185195
wait_start = time.time()
186196
while not task_started and (time.time() - wait_start) < 10:
@@ -193,11 +203,21 @@ def process_messages(scripts_state):
193203
logs += msg["text"] + "\n"
194204
yield logs, scripts, gr.update(choices=script_names, value=selected_script), scripts.get(selected_script, "") if selected_script else ""
195205
break
206+
elif msg_type == "error":
207+
logs += f"ERROR: {data}\n"
208+
yield logs, scripts, gr.update(choices=script_names, value=selected_script), scripts.get(selected_script, "") if selected_script else ""
209+
return
196210
except Empty:
197211
yield logs, scripts, gr.update(choices=script_names, value=selected_script), scripts.get(selected_script, "") if selected_script else ""
198212
time.sleep(0.1)
213+
except Exception as e:
214+
error_msg = f"ERROR waiting for task: {str(e)}"
215+
logs += error_msg + "\n"
216+
yield logs, scripts, gr.update(choices=script_names, value=selected_script), scripts.get(selected_script, "") if selected_script else ""
217+
return
199218

200219
if not task_started:
220+
logs += "ERROR: Task did not start within 10 seconds. Check websocket connection.\n"
201221
yield logs, scripts, gr.update(choices=script_names, value=selected_script), scripts.get(selected_script, "") if selected_script else ""
202222
return
203223

@@ -233,16 +253,18 @@ def process_messages(scripts_state):
233253
def toggle_settings(current_visible):
234254
return not current_visible, gr.update(visible=not current_visible)
235255

236-
def apply_settings(agent_dir, scripts_dir):
256+
def apply_settings(agent_dir, agent_pattern, scripts_dir):
237257
new_agent_dir = agent_dir.strip() if agent_dir and agent_dir.strip() else str(DEFAULT_AGENT_DIR)
258+
new_agent_pattern = agent_pattern.strip() if agent_pattern and agent_pattern.strip() else DEFAULT_AGENT_PATTERN
238259
new_scripts_dir = scripts_dir.strip() if scripts_dir and scripts_dir.strip() else str(DEFAULT_TESTS_DIR)
239260

240-
agent_choices = scan_agent_scripts(new_agent_dir)
261+
agent_choices = scan_agent_scripts(new_agent_dir, new_agent_pattern)
241262
scripts_choices = scan_script_dirs(new_scripts_dir)
242263
version_choices = scan_versions(new_agent_dir)
243264

244265
return (
245266
new_agent_dir,
267+
new_agent_pattern,
246268
new_scripts_dir,
247269
gr.update(choices=agent_choices, value=agent_choices[0] if agent_choices else None),
248270
gr.update(choices=scripts_choices, value=None),
@@ -252,7 +274,12 @@ def apply_settings(agent_dir, scripts_dir):
252274
)
253275

254276
def send_and_clear(agent_script, scripts_dir, agent_dir_state_val, scripts_dir_state_val):
255-
if agent_script and scripts_dir:
277+
try:
278+
if not agent_script:
279+
return "ERROR: No agent script selected"
280+
if not scripts_dir:
281+
return "ERROR: No scripts directory selected"
282+
256283
agent_dir = Path(agent_dir_state_val) if agent_dir_state_val else DEFAULT_AGENT_DIR
257284
scripts_base_dir = Path(scripts_dir_state_val) if scripts_dir_state_val else DEFAULT_TESTS_DIR
258285

@@ -264,13 +291,19 @@ def send_and_clear(agent_script, scripts_dir, agent_dir_state_val, scripts_dir_s
264291
output_queue.get_nowait()
265292
except Empty:
266293
break
294+
295+
if not ws_thread or not ws_thread.is_alive():
296+
return "ERROR: Websocket not connected. Try refreshing the page."
297+
267298
msg = json.dumps({
268299
"agent_script": agent_script,
269300
"scripts_dir": scripts_dir,
270301
"agent_dir": str(agent_dir)
271302
})
272303
message_queue.put(msg)
273-
return ""
304+
return ""
305+
except Exception as e:
306+
return f"ERROR in send_and_clear: {str(e)}"
274307

275308
def load_version_scripts(version, agent_dir_state_val):
276309
"""Load scripts directly from a version directory"""
@@ -333,17 +366,28 @@ def close_settings():
333366

334367
apply_settings_btn.click(
335368
apply_settings,
336-
inputs=[agent_dir_input, scripts_dir_input],
337-
outputs=[agent_dir_state, scripts_dir_state, agent_dropdown, scripts_dropdown, version_dropdown, settings_visible, settings_modal]
369+
inputs=[agent_dir_input, agent_pattern_input, scripts_dir_input],
370+
outputs=[agent_dir_state, agent_pattern_state, scripts_dir_state, agent_dropdown, scripts_dropdown, version_dropdown, settings_visible, settings_modal]
338371
)
339372

340373
def refresh_versions(agent_dir_state_val):
341374
"""Refresh version list"""
342375
versions = scan_versions(agent_dir_state_val)
343376
return gr.update(choices=versions)
344377

378+
def refresh_agents(agent_dir_state_val, agent_pattern_state_val):
379+
"""Refresh agent list"""
380+
agents = scan_agent_scripts(agent_dir_state_val, agent_pattern_state_val)
381+
return gr.update(choices=agents, value=agents[0] if agents else None)
382+
383+
def run_with_error_check(agent_script, scripts_dir, agent_dir_state_val, scripts_dir_state_val):
384+
error_msg = send_and_clear(agent_script, scripts_dir, agent_dir_state_val, scripts_dir_state_val)
385+
if error_msg:
386+
return error_msg
387+
return ""
388+
345389
run_btn.click(
346-
send_and_clear,
390+
run_with_error_check,
347391
inputs=[agent_dropdown, scripts_dropdown, agent_dir_state, scripts_dir_state],
348392
outputs=[output_logs]
349393
).then(
@@ -354,6 +398,10 @@ def refresh_versions(agent_dir_state_val):
354398
refresh_versions,
355399
inputs=[agent_dir_state],
356400
outputs=[version_dropdown]
401+
).then(
402+
refresh_agents,
403+
inputs=[agent_dir_state, agent_pattern_state],
404+
outputs=[agent_dropdown]
357405
)
358406

359407
reset_btn.click(

0 commit comments

Comments
 (0)