core / pages /2_Control_Panel.py
tensorus's picture
Upload 83 files
edfa748 verified
# pages/2_Control_Panel.py (Modifications for Step 3)
import streamlit as st
import time
import json
# Use the updated API-backed functions
from .ui_utils import (
list_all_agents,
get_agent_status,
get_agent_logs,
start_agent,
stop_agent,
update_agent_config,
)
st.set_page_config(page_title="Agent Control Panel", layout="wide")
st.title("🕹️ Multi-Agent Control Panel")
st.caption("Manage and monitor Tensorus agents via API.")
# Fetch agent list from API
agent_list = list_all_agents()
if not agent_list:
st.error("Could not fetch agent list from API. Please ensure the backend is running and reachable.")
st.stop()
# Create a mapping from name to ID for easier selection
# Handle potential duplicate names if necessary, though IDs should be unique
agent_options = {agent['name']: agent['id'] for agent in agent_list}
# Add ID to name if names aren't unique (optional robustness)
# agent_options = {f"{agent['name']} ({agent['id']})": agent['id'] for agent in agent_list}
selected_agent_name = st.selectbox("Select Agent:", options=agent_options.keys())
if selected_agent_name:
selected_agent_id = agent_options[selected_agent_name]
st.divider()
st.subheader(f"Control: {selected_agent_name} (`{selected_agent_id}`)")
# Use session state to store fetched status and logs for the selected agent
# This avoids refetching constantly unless a refresh is triggered
agent_state_key = f"agent_status_{selected_agent_id}"
agent_logs_key = f"agent_logs_{selected_agent_id}"
# Button to force refresh status and logs
if st.button(f"🔄 Refresh Status & Logs##{selected_agent_id}"): # Unique key per agent
st.session_state[agent_state_key] = get_agent_status(selected_agent_id)
st.session_state[agent_logs_key] = get_agent_logs(selected_agent_id)
st.rerun() # Rerun to display refreshed data
# Fetch status if not in session state or refresh button wasn't just clicked
if agent_state_key not in st.session_state:
st.session_state[agent_state_key] = get_agent_status(selected_agent_id)
status_info = st.session_state[agent_state_key]
if status_info:
status = status_info.get('status', 'unknown')
status_color = "green" if status in ["running", "starting"] else ("orange" if status in ["stopping"] else ("red" if status in ["error"] else "grey"))
st.markdown(f"Current Status: :{status_color}[**{status.upper()}**]")
last_log_ts = status_info.get('last_log_timestamp')
if last_log_ts:
st.caption(f"Last Log Entry (approx.): {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(last_log_ts))}")
else:
st.error(f"Could not retrieve status for agent '{selected_agent_name}'.")
# Control Buttons (Now call API functions)
col1, col2, col3 = st.columns([1, 1, 5])
is_running = status_info and status_info.get('status') == 'running'
is_stopped = status_info and status_info.get('status') == 'stopped'
with col1:
start_disabled = not is_stopped # Disable if not stopped
if st.button("▶️ Start", key=f"start_{selected_agent_id}", disabled=start_disabled):
if start_agent(selected_agent_id): # API call returns success/fail
# Trigger refresh after short delay to allow backend state change (optimistic)
time.sleep(1.0)
# Clear state cache and rerun
if agent_state_key in st.session_state: del st.session_state[agent_state_key]
if agent_logs_key in st.session_state: del st.session_state[agent_logs_key]
st.rerun()
with col2:
stop_disabled = not is_running # Disable if not running
if st.button("⏹️ Stop", key=f"stop_{selected_agent_id}", disabled=stop_disabled):
if stop_agent(selected_agent_id): # API call returns success/fail
time.sleep(1.0)
if agent_state_key in st.session_state: del st.session_state[agent_state_key]
if agent_logs_key in st.session_state: del st.session_state[agent_logs_key]
st.rerun()
st.divider()
# Configuration & Logs
tab1, tab2 = st.tabs(["Configuration", "Logs"])
with tab1:
if status_info and 'config' in status_info:
current_config = status_info['config']
st.write("Current configuration:")
st.json(current_config)
with st.expander("Edit configuration"):
form = st.form(key=f"cfg_form_{selected_agent_id}")
config_text = form.text_area(
"Configuration JSON",
value=json.dumps(current_config, indent=2),
height=200,
)
submitted = form.form_submit_button("Update")
if submitted:
try:
new_cfg = json.loads(config_text)
if update_agent_config(selected_agent_id, new_cfg):
if agent_state_key in st.session_state:
del st.session_state[agent_state_key]
time.sleep(0.5)
st.rerun()
except json.JSONDecodeError as e:
form.error(f"Invalid JSON: {e}")
else:
st.warning("Configuration not available.")
with tab2:
st.write("Recent logs (fetched from API):")
# Fetch logs if not in session state
if agent_logs_key not in st.session_state:
st.session_state[agent_logs_key] = get_agent_logs(selected_agent_id)
logs = st.session_state[agent_logs_key]
if logs is not None:
st.code("\n".join(logs), language="log")
else:
st.error("Could not retrieve logs.")
else:
st.info("Select an agent from the dropdown above.")