new(Streamlit):"import streamlit as st
import subprocess
import os
import shutil
import time
import threading
import queue
import yaml
import logging

# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

def read_config(*config_files):
    config = {}
    for file in config_files:
        with open(file, 'r') as f:
            config.update(yaml.safe_load(f))
    return config

def upload_agent(agent, agent_file, config_file, custom_agent_name, learning_rate, batch_size, epochs, gamma,
                 epsilon, epsilon_min, epsilon_decay, ngpu, thread_num, seed, debug, interface, delay_type,
                 task, world, network, dataset, prefix):
    start_time = time.time()  # Add this line at the beginning of the function
    workspace_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
    agent_dir = os.path.join(workspace_dir, 'agent')
    config_dir = os.path.join(workspace_dir, 'configs', 'tsc')

    logging.info(f"Workspace directory: {workspace_dir}")
    logging.info(f"Agent directory: {agent_dir}")
    logging.info(f"Config directory: {config_dir}")

    # Ensure directories exist
    os.makedirs(agent_dir, exist_ok=True)
    os.makedirs(config_dir, exist_ok=True)

    base_config_path = os.path.join(config_dir, 'base.yml')
    config = read_config(base_config_path)

    # Initialize variables
    agent_rel_path = ""
    config_rel_path = ""
    env_agent = ""

    if agent == "custom":
        logging.info("Handling custom agent upload")
        # Validate inputs
        if not agent_file or not config_file:
            error_msg = "Error: Custom agent requires both agent file and config file to be uploaded."
            logging.error(error_msg)
            return error_msg

        if not custom_agent_name:
            error_msg = "Error: Custom agent name is required."
            logging.error(error_msg)
            return error_msg

        # Get original filenames
        agent_filename = os.path.basename(agent_file.name)
        config_filename = os.path.basename(config_file.name)

        agent_rel_path = os.path.join('agent', agent_filename)
        config_rel_path = os.path.join('configs', 'tsc', config_filename)

        agent_path = os.path.join(workspace_dir, agent_rel_path)
        config_path = os.path.join(workspace_dir, config_rel_path)

        logging.info(f"Saving agent file to: {agent_path}")
        logging.info(f"Saving config file to: {config_path}")

        # Save the uploaded files
        try:
            with open(agent_path, 'wb') as f:
                f.write(agent_file.getbuffer())
            with open(config_path, 'wb') as f:
                f.write(config_file.getbuffer())
            logging.info("Files uploaded successfully.")

            # Update __init__.py file
            init_file_path = os.path.join(agent_dir, '__init__.py')
            agent_module_name = os.path.splitext(agent_filename)[0]

            # Read the existing __init__.py content
            if os.path.exists(init_file_path):
                with open(init_file_path, 'r') as init_file:
                    init_content = init_file.read()
            else:
                init_content = ''

            # Prepare import line
            import_line = f"from .{agent_module_name} import {custom_agent_name}\n"

            # Add the import line if not already present
            if import_line not in init_content:
                with open(init_file_path, 'a') as init_file:
                    init_file.write("\n")  # Add a newline before the import
                    init_file.write(import_line)
                logging.info(f"Updated {init_file_path} with: {import_line.strip()}")

            # Save paths for deletion upon reset
            st.session_state['agent_file_path'] = agent_path
            st.session_state['config_file_path'] = config_path
            st.session_state['init_file_path'] = init_file_path
            st.session_state['import_line'] = import_line

        except Exception as e:
            error_msg = f"Error saving files or updating __init__.py: {str(e)}"
            logging.error(error_msg)
            return error_msg

        # Read the uploaded custom config file
        custom_config = read_config(config_path)
        config.update(custom_config)

        env_agent = custom_agent_name

    else:
        logging.info(f"Handling predefined agent: {agent}")
        # Define filenames for predefined agents
        agent_filename = f"{agent}.py"
        config_filename = f"{agent}.yml"

        agent_rel_path = os.path.join('agent', agent_filename)
        config_rel_path = os.path.join('configs', 'tsc', config_filename)

        agent_path = os.path.join(workspace_dir, agent_rel_path)
        config_path = os.path.join(workspace_dir, config_rel_path)

        logging.info(f"Using agent file: {agent_path}")
        logging.info(f"Using config file: {config_path}")

        # Check if config file exists and update config
        if os.path.exists(config_path):
            agent_config = read_config(config_path)
            config.update(agent_config)
            logging.info("Predefined agent config loaded.")
        else:
            logging.warning(f"Config file {config_path} does not exist. Using base config.")

        env_agent = agent_filename

    # Set environment variables (if necessary)
    # os.environ['AGENT'] = agent_filename
    # ... (other environment variables)

    logging.info("Environment variables set for deployment.")
    print('agent_rel_path', agent_rel_path)
    print('config_rel_path', config_rel_path)
    print('env_agent', env_agent)
    print('agent_filename', agent_filename)
    print('config_filename', config_filename)

    output_queue = queue.Queue()

    def run_subprocess():
        try:
            command = [
                'python', 'SimTrafficOpt/core/drl_deployment.py',
                '--agent', agent_filename[:-3],
                '--agent_file', agent_rel_path,
                '--config_file', config_rel_path,
                '--ngpu', ngpu,
                '--thread_num', str(thread_num),
                '--prefix', prefix,
                '--seed', str(seed) if seed is not None else '',
                '--debug', str(debug).lower(),
                '--interface', interface,
                '--delay_type', delay_type,
                '-t', task,
                '-w', world,
                '-n', network,
                '-d', dataset,
                #'--learning_rate', str(learning_rate),
                #'--batch_size', str(batch_size),
                #'--epochs', str(epochs),
                #'--gamma', str(gamma),
                #'--epsilon', str(epsilon),
                #'--epsilon_min', str(epsilon_min),
                #'--epsilon_decay', str(epsilon_decay)
            ]

            drl_process = subprocess.Popen(
                command,
                cwd=workspace_dir,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                env=os.environ,
                bufsize=1,
                universal_newlines=True
            )

            for line in drl_process.stdout:
                output_queue.put(line.strip())
                print(line.strip())  # Print to console for debugging
            for line in drl_process.stderr:
                output_queue.put(f"ERROR: {line.strip()}")
                print(f"ERROR: {line.strip()}")  # Print to console for debugging

            drl_process.wait()
            return_code = drl_process.returncode
            output_queue.put(f"Subprocess exited with return code {return_code}")
            print(f"Subprocess exited with return code {return_code}")  # Print to console for debugging
        except Exception as e:
            error_msg = f"Error running subprocess: {str(e)}"
            output_queue.put(error_msg)
            print(error_msg)  # Print to console for debugging

    subprocess_thread = threading.Thread(target=run_subprocess)
    subprocess_thread.start()

    outputs = []

    while subprocess_thread.is_alive() or not output_queue.empty():
        try:
            line = output_queue.get_nowait()
            outputs.append(line)
        except queue.Empty:
            time.sleep(0.1)
        if time.time() - start_time > 300:  # 5 minutes timeout
            outputs.append("Deployment timed out after 5 minutes.")
            break

    subprocess_thread.join()
    return outputs

def get_config(agent_type):
    workspace_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
    base_config_path = os.path.join(workspace_dir, 'configs', 'tsc', 'base.yml')
    agent_config_path = os.path.join(workspace_dir, 'configs', 'tsc', f'{agent_type}.yml')

    if os.path.exists(agent_config_path):
        return read_config(base_config_path, agent_config_path)
    else:
        return read_config(base_config_path)

def load_config_file(config_file):
    if config_file is None:
        return [None] * 7  # Return None for each field

    try:
        new_config = yaml.safe_load(config_file.getvalue())
        return (
            new_config.get('model', {}).get('learning_rate', 0.001),
            new_config.get('model', {}).get('batch_size', 64),
            new_config.get('trainer', {}).get('episodes', 200),
            new_config.get('model', {}).get('gamma', 0.95),
            new_config.get('model', {}).get('epsilon', 0.5),
            new_config.get('model', {}).get('epsilon_min', 0.05),
            new_config.get('model', {}).get('epsilon_decay', 0.99)
        )
    except Exception as e:
        logging.error(f"Error loading config file: {str(e)}")
        st.error(f"Error loading config file: {str(e)}")
        return [None] * 7

def main():
    st.markdown("## Dynamic Agent Customization")

    # Agent Selection
    agent_options = ["colight", "dqn", "presslight", "frap", "maxpressure", "mplight", "sotl", "custom"]
    agent = st.selectbox("Agent type", options=agent_options, index=agent_options.index("dqn"), key='agent_select')

    # Function to get default config
    config = get_config(agent)

    # Initialize parameter variables
    learning_rate = config.get('model', {}).get('learning_rate', 0.001)
    batch_size = config.get('model', {}).get('batch_size', 64)
    epochs = config.get('trainer', {}).get('episodes', 200)
    gamma = config.get('model', {}).get('gamma', 0.95)
    epsilon = config.get('model', {}).get('epsilon', 0.5)
    epsilon_min = config.get('model', {}).get('epsilon_min', 0.05)
    epsilon_decay = config.get('model', {}).get('epsilon_decay', 0.99)

    agent_file = None
    config_file = None
    custom_agent_name = None

    if agent == "custom":
        st.markdown("### Custom Agent Inputs")
        cols = st.columns([2, 2, 1])
        with cols[0]:
            agent_file = st.file_uploader("Agent File (.py)", type=['py'], key='agent_file_uploader')
        with cols[1]:
            config_file = st.file_uploader("Config File (.yml)", type=['yml'], key='config_file_uploader')
        with cols[2]:
            custom_agent_name = st.text_input("Custom Agent Name (e.g., TestLightAgent, CoLightAgent)", key='custom_agent_name_input')
        load_config_button = st.button("Load Config", key='load_config_button')

        if load_config_button:
            if config_file is not None:
                lr, bs, ep, gm, eps, eps_min, eps_dec = load_config_file(config_file)
                if None not in [lr, bs, ep, gm, eps, eps_min, eps_dec]:
                    learning_rate = lr
                    batch_size = bs
                    epochs = ep
                    gamma = gm
                    epsilon = eps
                    epsilon_min = eps_min
                    epsilon_decay = eps_dec
            else:
                st.error("Please upload a config file before loading.")
    else:
        # Reset any stored file paths for custom files
        st.session_state.pop('agent_file_path', None)
        st.session_state.pop('config_file_path', None)
        st.session_state.pop('init_file_path', None)
        st.session_state.pop('import_line', None)

    # Agent Settings
    st.markdown("### Agent Settings - currently unsupported")
    with st.expander("Agent Settings", expanded=False):
        cols = st.columns(3)
        with cols[0]:
            learning_rate = st.slider("Learning Rate", min_value=0.0001, max_value=0.1, value=learning_rate,
                                      step=0.0001, format="%.4f", key='learning_rate_slider', disabled=True)
        with cols[1]:
            batch_size = st.slider("Batch Size", min_value=8, max_value=256, value=batch_size, step=8, key='batch_size_slider', disabled=True)
        with cols[2]:
            epochs = st.slider("Epochs", min_value=1, max_value=1000, value=epochs, step=1, key='epochs_slider', disabled=True)

        cols = st.columns(3)
        with cols[0]:
            gamma = st.slider("Gamma", min_value=0.1, max_value=1.0, value=gamma, step=0.01, key='gamma_slider', disabled=True)
        with cols[1]:
            epsilon = st.slider("Epsilon", min_value=0.0, max_value=1.0, value=epsilon, step=0.01, key='epsilon_slider', disabled=True)
        with cols[2]:
            epsilon_min = st.slider("Epsilon Min", min_value=0.0, max_value=1.0, value=epsilon_min, step=0.01, key='epsilon_min_slider', disabled=True)
        epsilon_decay = st.slider("Epsilon Decay", min_value=0.9, max_value=1.0, value=epsilon_decay, step=0.01, key='epsilon_decay_slider', disabled=True)

    # Simulation Settings
    st.markdown("### Simulation Settings")
    with st.expander("Simulation Settings"):
        cols = st.columns(3)
        with cols[0]:
            world = st.selectbox("Simulator type", options=["cityflow", "sumo"], index=1, key='world_select')
            network = st.text_input("Network name", value="sumo1x1", key='network_input')
            dataset = st.text_input("Type of dataset in training process", value="onfly", key='dataset_input')
        with cols[1]:
            task = st.selectbox("Task type to run", options=["tsc", "inference"], index=0, key='task_select')
            delay_type = st.selectbox("Method of calculating delay", options=["apx", "real"], index=0, key='delay_type_select')
            interface = st.selectbox("Interface type", options=["libsumo", "traci"], index=0, key='interface_select')

    # Advanced Settings
    st.markdown("### Advanced Settings")
    with st.expander("Advanced Settings"):
        cols = st.columns(3)
        with cols[0]:
            ngpu = st.text_input("GPU to be used", value="-1", key='ngpu_input')
            thread_num = st.slider("Number of threads", min_value=1, max_value=16, value=4, step=1, key='thread_num_slider')
        with cols[1]:
            prefix = st.text_input("Prefix for this running process", value="test", key='prefix_input')
            seed = st.number_input("Seed for pytorch backend", value=0, key='seed_input')
        with cols[2]:
            debug = st.checkbox("Debug mode", value=True, key='debug_checkbox')

    # Buttons with unique keys
    cols = st.columns(2)
    with cols[0]:
        upload_button = st.button("Upload and Deploy Agent", key='upload_button')
    with cols[1]:
        reset_button = st.button("Reset", key='reset_button')

    # Output
    output_placeholder = st.empty()

    if reset_button:
        # Delete custom agent and config files if they exist
        agent_file_path = st.session_state.pop('agent_file_path', None)
        config_file_path = st.session_state.pop('config_file_path', None)
        init_file_path = st.session_state.pop('init_file_path', None)
        import_line = st.session_state.pop('import_line', None)
        if agent_file_path and os.path.exists(agent_file_path):
            os.remove(agent_file_path)
        if config_file_path and os.path.exists(config_file_path):
            os.remove(config_file_path)
        if init_file_path and os.path.exists(init_file_path) and import_line:
            # Remove the import line from __init__.py
            with open(init_file_path, 'r') as file:
                lines = file.readlines()
            with open(init_file_path, 'w') as file:
                for line in lines:
                    if line.strip("\n") != import_line.strip("\n"):
                        file.write(line)
        st.success("Custom agent and config files have been deleted.")
        st.experimental_rerun()

    if upload_button:
        # Validate custom agent inputs
        if agent == "custom":
            if not agent_file or not config_file or not custom_agent_name:
                st.error("Please provide all required custom agent inputs.")
                return

        start_time = time.time()
        with st.spinner("Uploading and deploying agent..."):
            outputs = upload_agent(
                agent, agent_file, config_file, custom_agent_name, learning_rate, batch_size, epochs,
                gamma, epsilon, epsilon_min, epsilon_decay, ngpu, thread_num, seed, debug,
                interface, delay_type, task, world, network, dataset, prefix
            )
            output_text = ""
            for output_line in outputs:
                output_text += output_line
                output_placeholder.text_area("Output", value=output_text, height=300)
                time.sleep(0.1)

    # Display initial output if not running
    if not upload_button and not reset_button:
        output_placeholder.text_area("Output", value="", height=300)

if __name__ == "__main__":
    main()"


doesnt log file like old gradio:"import gradio as gr
import subprocess
import tempfile
import os
import shutil
import time

def upload_agent(agent_file, config_file, learning_rate, batch_size, epochs, gamma, epsilon, epsilon_min, epsilon_decay, ngpu, thread_num, prefix, seed, debug, interface, delay_type, task, agent, world, network, dataset):
    workspace_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
    agent_dir = os.path.join(workspace_dir, 'agent')
    config_dir = os.path.join(workspace_dir, 'configs', 'tsc')

    os.makedirs(agent_dir, exist_ok=True)
    os.makedirs(config_dir, exist_ok=True)

    timestamp = int(time.time())
    agent_filename = f"agent_{timestamp}.py"
    config_filename = f"config_{timestamp}.yml"

    agent_path = os.path.join(agent_dir, agent_filename)
    config_path = os.path.join(config_dir, config_filename)

    shutil.copy(agent_file.name, agent_path)
    shutil.copy(config_file.name, config_path)

    env = os.environ.copy()
    env['LEARNING_RATE'] = str(learning_rate)
    env['BATCH_SIZE'] = str(batch_size)
    env['EPOCHS'] = str(epochs)
    env['GAMMA'] = str(gamma)
    env['EPSILON'] = str(epsilon)
    env['EPSILON_MIN'] = str(epsilon_min)
    env['EPSILON_DECAY'] = str(epsilon_decay)
    env['NGPU'] = str(ngpu)
    env['THREAD_NUM'] = str(thread_num)
    env['PREFIX'] = str(prefix)
    env['SEED'] = str(seed) if seed is not None else ''
    env['DEBUG'] = str(debug).lower()
    env['INTERFACE'] = interface
    env['DELAY_TYPE'] = delay_type
    env['TASK'] = task
    env['AGENT'] = agent
    env['WORLD'] = world
    env['NETWORK'] = network
    env['DATASET'] = dataset

    drl_process = subprocess.Popen(
        ['python', 'SimTrafficOpt/core/drl_deployment.py',
         '--agent_file', agent_path,
         '--config_file', config_path,
         '--ngpu', ngpu,
         '--thread_num', str(thread_num),
         '--prefix', prefix,
         '--seed', str(seed) if seed is not None else '',
         '--debug', str(debug).lower(),
         '--interface', interface,
         '--delay_type', delay_type,
         '-t', task,
         '-a', agent,
         '-w', world,
         '-n', network,
         '-d', dataset],
        cwd=workspace_dir,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        env=env
    )

    stdout, stderr = drl_process.communicate()

    cleanup(agent_path, config_path)

    return f"STDOUT:\n{stdout.decode()}\nSTDERR:\n{stderr.decode()}\nModel Performance: datachart"



def cleanup(agent_path, config_path):
    if os.path.exists(agent_path):
        os.remove(agent_path)
    if os.path.exists(config_path):
        os.remove(config_path)

def reset():
    workspace_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
    agent_dir = os.path.join(workspace_dir, 'agent')
    config_dir = os.path.join(workspace_dir, 'configs', 'tsc')

    for file in os.listdir(agent_dir):
        if file.startswith("agent_"):
            os.remove(os.path.join(agent_dir, file))
    
    for file in os.listdir(config_dir):
        if file.startswith("config_"):
            os.remove(os.path.join(config_dir, file))

    return "Reset complete. All temporary files removed."

# The rest of the file remains the same

def create_dynamic_agent_customization_ui():
    with gr.Blocks() as dynamic_agent_customization:
        gr.Markdown("## Dynamic Agent Customization")
        with gr.Row():
            agent_file = gr.File(label="Upload Agent File (.py)")
            config_file = gr.File(label="Upload Config File (.yml)")
        
        with gr.Accordion("Advanced Settings"):
            with gr.Row():
                learning_rate = gr.Slider(minimum=0.0001, maximum=0.1, value=0.001, label="Learning Rate")
                batch_size = gr.Slider(minimum=8, maximum=256, step=8, value=32, label="Batch Size")
                epochs = gr.Slider(minimum=1, maximum=100, step=1, value=10, label="Epochs")
            with gr.Row():
                gamma = gr.Slider(minimum=0.1, maximum=1.0, value=0.99, label="Gamma")
                epsilon = gr.Slider(minimum=0.0, maximum=1.0, value=1.0, label="Epsilon")
                epsilon_min = gr.Slider(minimum=0.0, maximum=1.0, value=0.01, label="Epsilon Min")
                epsilon_decay = gr.Slider(minimum=0.9, maximum=1.0, value=0.995, label="Epsilon Decay")
            with gr.Row():
                ngpu = gr.Textbox(value="-1", label="GPU to be used")
                thread_num = gr.Slider(minimum=1, maximum=16, step=1, value=4, label="Number of threads")
            with gr.Row():
                prefix = gr.Textbox(value="test", label="Prefix for this running process")
                seed = gr.Number(value=None, label="Seed for pytorch backend")
            with gr.Row():
                debug = gr.Checkbox(value=True, label="Debug mode")
                interface = gr.Dropdown(choices=["libsumo", "traci"], value="libsumo", label="Interface type")
            with gr.Row():
                delay_type = gr.Dropdown(choices=["apx", "real"], value="apx", label="Method of calculating delay")
                task = gr.Textbox(value="tsc", label="Task type to run")
            with gr.Row():
                agent = gr.Textbox(value="frap", label="Agent type")
                world = gr.Dropdown(choices=["cityflow", "sumo"], value="sumo", label="Simulator type")
            with gr.Row():
                network = gr.Textbox(value="sumo1x1", label="Network name")
                dataset = gr.Textbox(value="onfly", label="Type of dataset in training process")

        upload_button = gr.Button("Upload and Deploy Agent")
        reset_button = gr.Button("Reset")
        output = gr.Textbox(label="Output")

        upload_button.click(fn=upload_agent, inputs=[agent_file, config_file, learning_rate, batch_size, epochs, gamma, epsilon, epsilon_min, epsilon_decay, ngpu, thread_num, prefix, seed, debug, interface, delay_type, task, agent, world, network, dataset], outputs=output)
        reset_button.click(fn=reset, outputs=output)

    return dynamic_agent_customization"