Spaces:
Runtime error
Runtime error
| # ==================== Import Standard Libraries ==================== | |
| import os | |
| import sys | |
| import uuid | |
| import uuid | |
| import uuid | |
| # ==================== Set Paths ==================== | |
| current_dir = os.path.dirname(os.path.abspath(__file__)) | |
| # ==================== Fix huggingface_hub Compatibility ==================== | |
| def _fix_huggingface_hub(): | |
| """Fix huggingface_hub compatibility issues""" | |
| try: | |
| import huggingface_hub | |
| if not hasattr(huggingface_hub, 'HfFolder'): | |
| class HfFolder: | |
| def save_token(token): | |
| pass | |
| def get_token(): | |
| return None | |
| def get_token_path(): | |
| return None | |
| huggingface_hub.HfFolder = HfFolder | |
| if hasattr(huggingface_hub, '__all__'): | |
| if 'HfFolder' not in huggingface_hub.__all__: | |
| huggingface_hub.__all__.append('HfFolder') | |
| except Exception: | |
| pass | |
| _fix_huggingface_hub() | |
| # ==================== Import Third-Party Libraries ==================== | |
| import gradio as gr | |
| # ==================== Import Task Modules ==================== | |
| # Each task has an independent module file containing all logic and interface components for that task | |
| # Task module naming convention: GUI_{TaskName}_Task.py | |
| import GUI_Light_Task as light_task | |
| import GUI_Repo_Task as repo_task | |
| import GUI_Trade_Task as trade_task | |
| import GUI_Energy_Task as energy_task | |
| # ==================== Import Unified Progress Management Module ==================== | |
| import progress_manager | |
| # ------------------- Global Variables (for saving directories and other configurations) ------------------- | |
| # Use user_progress under project directory uniformly (consistent for local and remote) | |
| save_dir = os.path.join(current_dir, "user_progress") | |
| # Ensure directory exists | |
| os.makedirs(save_dir, exist_ok=True) | |
| # Detect running environment | |
| IS_HUGGINGFACE = progress_manager.is_running_on_huggingface() | |
| RUN_MODE = progress_manager.get_run_mode() | |
| # ==================== Unified Interface ==================== | |
| def create_interface(): | |
| """Create unified multi-task interface""" | |
| with gr.Blocks(title="Multi-Task Environment Interface") as demo: | |
| # Display different titles based on running environment | |
| if IS_HUGGINGFACE: | |
| gr.Markdown(""" | |
| # ๐ฎ Multi-Task Environment Interface (Hugging Face Version) | |
| Supports multiple task environments. Use task switching buttons to select different tasks. | |
| """) | |
| else: | |
| gr.Markdown(""" | |
| # ๐ฎ Multi-Task Environment Interface (Local Version) | |
| Supports multiple task environments. Use task switching buttons to select different tasks. | |
| """) | |
| # ==================== Create State Objects (Independent for Each User Session) ==================== | |
| # These state objects ensure data isolation during multi-user concurrency | |
| light_state = gr.State(light_task.create_light_state()) | |
| repo_state = gr.State(repo_task.create_repo_state()) | |
| trade_state = gr.State(trade_task.create_trade_state()) | |
| energy_state = gr.State(energy_task.create_energy_state()) | |
| # Current task type state | |
| current_task_type = gr.State("light") | |
| # Auto-generate default user ID for each session (no user input required) | |
| default_user_id = gr.State(f"user_{uuid.uuid4().hex[:8]}") | |
| # ==================== Task Switching Buttons ==================== | |
| gr.Markdown("---") | |
| gr.Markdown("### ๐ฏ Select Task") | |
| with gr.Row(): | |
| task_light_btn = gr.Button("๐ก Light Task", variant="primary") | |
| task_repo_btn = gr.Button("๐ฆ Repo Task", variant="secondary") | |
| task_trade_btn = gr.Button("๐น Trade Task", variant="secondary") | |
| task_energy_btn = gr.Button("โก Energy Task", variant="secondary") | |
| # ==================== Task Interface Area ==================== | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| # Light Task Environment Control | |
| light_env_control_markdown = gr.Markdown("### ๐ฎ Light Environment Control", visible=True) | |
| light_env_idx_input = gr.Number( | |
| label="Environment Index", | |
| value=1, | |
| minimum=1, | |
| maximum=30, | |
| precision=0, | |
| info="Select environment to load (1-30)", | |
| visible=True | |
| ) | |
| light_init_btn = gr.Button("Load Environment", variant="primary", visible=True) | |
| light_reset_btn = gr.Button("Reset Environment", visible=True) | |
| light_env_info = gr.Textbox(label="Environment Info", interactive=False, lines=5, visible=True) | |
| # Energy Task Environment Control | |
| energy_env_control_markdown = gr.Markdown("### ๐ฎ Energy Environment Control", visible=False) | |
| energy_env_idx_input = gr.Number( | |
| label="Environment Index", | |
| value=1, | |
| minimum=1, | |
| maximum=30, | |
| precision=0, | |
| info="Select environment to load (1-30)", | |
| visible=False | |
| ) | |
| energy_init_btn = gr.Button("Load Environment", variant="primary", visible=False) | |
| energy_reset_btn = gr.Button("Reset Environment", visible=False) | |
| energy_env_info = gr.Textbox(label="Environment Info", interactive=False, lines=5, visible=False) | |
| # Repo Task Environment Control | |
| repo_env_control_markdown = gr.Markdown("### ๐ฎ Repo Environment Control", visible=False) | |
| repo_env_idx_input = gr.Number( | |
| label="Environment Index", | |
| value=1, | |
| minimum=1, | |
| maximum=30, | |
| precision=0, | |
| info="Select environment to load (1-30)", | |
| visible=False | |
| ) | |
| repo_init_btn = gr.Button("Load Environment", variant="primary", visible=False) | |
| repo_reset_btn = gr.Button("Reset Environment", visible=False) | |
| repo_env_info = gr.Textbox(label="Environment Info", interactive=False, lines=5, visible=False) | |
| # Trade Task Environment Control | |
| trade_env_control_markdown = gr.Markdown("### ๐ฎ Trade Environment Control", visible=False) | |
| trade_env_idx_input = gr.Number( | |
| label="Environment Index", | |
| value=1, | |
| minimum=1, | |
| maximum=30, | |
| precision=0, | |
| info="Select environment to load (1-30)", | |
| visible=False | |
| ) | |
| trade_init_btn = gr.Button("Load Environment", variant="primary", visible=False) | |
| trade_reset_btn = gr.Button("Reset Environment", visible=False) | |
| trade_env_info = gr.Textbox(label="Environment Info", interactive=False, lines=5, visible=False) | |
| # Example Display | |
| example_display = gr.Markdown( | |
| label="๐ Usage Example", | |
| value=light_task.LIGHT_EXAMPLE_TEXT, | |
| visible=True | |
| ) | |
| # ==================== Create Task Interface Components ==================== | |
| # Each task module provides a create_{task}_interface() function | |
| # Returns all Gradio components required for that task | |
| # Light Task Interface Components | |
| (light_interface, _, _, _, | |
| _, light_state_display, light_steps_info_text, | |
| light_action_input, light_step_btn, light_feedback_display, light_history_display) = \ | |
| light_task.create_light_interface(current_dir, save_dir, None) | |
| # Repo Task Interface Components (environment control components created in main interface) | |
| (repo_interface, _, _, _, | |
| _, repo_state_display, repo_steps_info_text, | |
| repo_action_input, repo_step_btn, repo_feedback_display, repo_history_display) = \ | |
| repo_task.create_repo_interface(current_dir, save_dir, None) | |
| # Trade Task Interface Components (environment control components created in main interface) | |
| (trade_interface, _, _, _, | |
| _, trade_state_display, trade_steps_info_text, | |
| trade_stock_inputs, trade_step_btn, trade_feedback_display, trade_history_display) = \ | |
| trade_task.create_trade_interface(current_dir, save_dir, None) | |
| # Energy Task Interface Components (environment control components created in main interface) | |
| (energy_interface, _, _, _, | |
| _, energy_state_display, energy_steps_info_text, | |
| energy_thermal_input, energy_wind_input, energy_solar_input, energy_battery_input, | |
| energy_cost_display, energy_step_btn, energy_feedback_display, energy_history_display) = \ | |
| energy_task.create_energy_interface(current_dir, save_dir, None) | |
| # ==================== Task Switching Logic ==================== | |
| # Each task module provides: | |
| # 1. load_{task}_test_data() - Load test data | |
| # 2. {TASK}_EXAMPLE_TEXT - Example text constant | |
| def switch_to_light(state): | |
| """Switch to Light task""" | |
| # Load test data | |
| state, _ = light_task.load_light_test_data(state, current_dir) | |
| return ( | |
| state, | |
| "light", # current_task_type | |
| gr.update(visible=True), # light_interface | |
| gr.update(visible=False), # repo_interface | |
| gr.update(visible=False), # trade_interface | |
| gr.update(visible=False), # energy_interface | |
| gr.update(variant="primary"), # task_light_btn | |
| gr.update(variant="secondary"), # task_repo_btn | |
| gr.update(variant="secondary"), # task_trade_btn | |
| gr.update(variant="secondary"), # task_energy_btn | |
| light_task.LIGHT_EXAMPLE_TEXT, # example_display | |
| # Environment control component visibility | |
| gr.update(visible=True), # light_env_control_markdown | |
| gr.update(visible=True), # light_env_idx_input | |
| gr.update(visible=True), # light_init_btn | |
| gr.update(visible=True), # light_reset_btn | |
| gr.update(visible=True), # light_env_info | |
| gr.update(visible=False), # energy_env_control_markdown | |
| gr.update(visible=False), # energy_env_idx_input | |
| gr.update(visible=False), # energy_init_btn | |
| gr.update(visible=False), # energy_reset_btn | |
| gr.update(visible=False), # energy_env_info | |
| gr.update(visible=False), # repo_env_control_markdown | |
| gr.update(visible=False), # repo_env_idx_input | |
| gr.update(visible=False), # repo_init_btn | |
| gr.update(visible=False), # repo_reset_btn | |
| gr.update(visible=False), # repo_env_info | |
| gr.update(visible=False), # trade_env_control_markdown | |
| gr.update(visible=False), # trade_env_idx_input | |
| gr.update(visible=False), # trade_init_btn | |
| gr.update(visible=False), # trade_reset_btn | |
| gr.update(visible=False) # trade_env_info | |
| ) | |
| def switch_to_repo(state): | |
| """Switch to Repo task""" | |
| state, _ = repo_task.load_repo_test_data(state, current_dir) | |
| return ( | |
| state, | |
| "repo", | |
| gr.update(visible=False), # light_interface | |
| gr.update(visible=True), # repo_interface | |
| gr.update(visible=False), # trade_interface | |
| gr.update(visible=False), # energy_interface | |
| gr.update(variant="secondary"), # task_light_btn | |
| gr.update(variant="primary"), # task_repo_btn | |
| gr.update(variant="secondary"), # task_trade_btn | |
| gr.update(variant="secondary"), # task_energy_btn | |
| repo_task.REPO_EXAMPLE_TEXT, # example_display | |
| # Environment control component visibility | |
| gr.update(visible=False), # light_env_control_markdown | |
| gr.update(visible=False), # light_env_idx_input | |
| gr.update(visible=False), # light_init_btn | |
| gr.update(visible=False), # light_reset_btn | |
| gr.update(visible=False), # light_env_info | |
| gr.update(visible=False), # energy_env_control_markdown | |
| gr.update(visible=False), # energy_env_idx_input | |
| gr.update(visible=False), # energy_init_btn | |
| gr.update(visible=False), # energy_reset_btn | |
| gr.update(visible=False), # energy_env_info | |
| gr.update(visible=True), # repo_env_control_markdown | |
| gr.update(visible=True), # repo_env_idx_input | |
| gr.update(visible=True), # repo_init_btn | |
| gr.update(visible=True), # repo_reset_btn | |
| gr.update(visible=True), # repo_env_info | |
| gr.update(visible=False), # trade_env_control_markdown | |
| gr.update(visible=False), # trade_env_idx_input | |
| gr.update(visible=False), # trade_init_btn | |
| gr.update(visible=False), # trade_reset_btn | |
| gr.update(visible=False) # trade_env_info | |
| ) | |
| def switch_to_trade(state): | |
| """Switch to Trade task""" | |
| state, _ = trade_task.load_trade_test_data(state, current_dir) | |
| return ( | |
| state, | |
| "trade", | |
| gr.update(visible=False), # light_interface | |
| gr.update(visible=False), # repo_interface | |
| gr.update(visible=True), # trade_interface | |
| gr.update(visible=False), # energy_interface | |
| gr.update(variant="secondary"), # task_light_btn | |
| gr.update(variant="secondary"), # task_repo_btn | |
| gr.update(variant="primary"), # task_trade_btn | |
| gr.update(variant="secondary"), # task_energy_btn | |
| trade_task.TRADE_EXAMPLE_TEXT, # example_display | |
| # Environment control component visibility | |
| gr.update(visible=False), # light_env_control_markdown | |
| gr.update(visible=False), # light_env_idx_input | |
| gr.update(visible=False), # light_init_btn | |
| gr.update(visible=False), # light_reset_btn | |
| gr.update(visible=False), # light_env_info | |
| gr.update(visible=False), # energy_env_control_markdown | |
| gr.update(visible=False), # energy_env_idx_input | |
| gr.update(visible=False), # energy_init_btn | |
| gr.update(visible=False), # energy_reset_btn | |
| gr.update(visible=False), # energy_env_info | |
| gr.update(visible=False), # repo_env_control_markdown | |
| gr.update(visible=False), # repo_env_idx_input | |
| gr.update(visible=False), # repo_init_btn | |
| gr.update(visible=False), # repo_reset_btn | |
| gr.update(visible=False), # repo_env_info | |
| gr.update(visible=True), # trade_env_control_markdown | |
| gr.update(visible=True), # trade_env_idx_input | |
| gr.update(visible=True), # trade_init_btn | |
| gr.update(visible=True), # trade_reset_btn | |
| gr.update(visible=True) # trade_env_info | |
| ) | |
| def switch_to_energy(state): | |
| """Switch to Energy task""" | |
| state, _ = energy_task.load_energy_test_data(state, current_dir) | |
| return ( | |
| state, | |
| "energy", | |
| gr.update(visible=False), # light_interface | |
| gr.update(visible=False), # repo_interface | |
| gr.update(visible=False), # trade_interface | |
| gr.update(visible=True), # energy_interface | |
| gr.update(variant="secondary"), # task_light_btn | |
| gr.update(variant="secondary"), # task_repo_btn | |
| gr.update(variant="secondary"), # task_trade_btn | |
| gr.update(variant="primary"), # task_energy_btn | |
| energy_task.ENERGY_EXAMPLE_TEXT, # example_display | |
| # Environment control component visibility | |
| gr.update(visible=False), # light_env_control_markdown | |
| gr.update(visible=False), # light_env_idx_input | |
| gr.update(visible=False), # light_init_btn | |
| gr.update(visible=False), # light_reset_btn | |
| gr.update(visible=False), # light_env_info | |
| gr.update(visible=True), # energy_env_control_markdown | |
| gr.update(visible=True), # energy_env_idx_input | |
| gr.update(visible=True), # energy_init_btn | |
| gr.update(visible=True), # energy_reset_btn | |
| gr.update(visible=True), # energy_env_info | |
| gr.update(visible=False), # repo_env_control_markdown | |
| gr.update(visible=False), # repo_env_idx_input | |
| gr.update(visible=False), # repo_init_btn | |
| gr.update(visible=False), # repo_reset_btn | |
| gr.update(visible=False), # repo_env_info | |
| gr.update(visible=False), # trade_env_control_markdown | |
| gr.update(visible=False), # trade_env_idx_input | |
| gr.update(visible=False), # trade_init_btn | |
| gr.update(visible=False), # trade_reset_btn | |
| gr.update(visible=False) # trade_env_info | |
| ) | |
| task_light_btn.click( | |
| fn=switch_to_light, | |
| inputs=[light_state], | |
| outputs=[light_state, current_task_type, light_interface, repo_interface, trade_interface, energy_interface, | |
| task_light_btn, task_repo_btn, task_trade_btn, task_energy_btn, | |
| example_display, | |
| light_env_control_markdown, light_env_idx_input, light_init_btn, light_reset_btn, light_env_info, | |
| energy_env_control_markdown, energy_env_idx_input, energy_init_btn, energy_reset_btn, energy_env_info, | |
| repo_env_control_markdown, repo_env_idx_input, repo_init_btn, repo_reset_btn, repo_env_info, | |
| trade_env_control_markdown, trade_env_idx_input, trade_init_btn, trade_reset_btn, trade_env_info] | |
| ) | |
| task_repo_btn.click( | |
| fn=switch_to_repo, | |
| inputs=[repo_state], | |
| outputs=[repo_state, current_task_type, light_interface, repo_interface, trade_interface, energy_interface, | |
| task_light_btn, task_repo_btn, task_trade_btn, task_energy_btn, | |
| example_display, | |
| light_env_control_markdown, light_env_idx_input, light_init_btn, light_reset_btn, light_env_info, | |
| energy_env_control_markdown, energy_env_idx_input, energy_init_btn, energy_reset_btn, energy_env_info, | |
| repo_env_control_markdown, repo_env_idx_input, repo_init_btn, repo_reset_btn, repo_env_info, | |
| trade_env_control_markdown, trade_env_idx_input, trade_init_btn, trade_reset_btn, trade_env_info] | |
| ) | |
| task_trade_btn.click( | |
| fn=switch_to_trade, | |
| inputs=[trade_state], | |
| outputs=[trade_state, current_task_type, light_interface, repo_interface, trade_interface, energy_interface, | |
| task_light_btn, task_repo_btn, task_trade_btn, task_energy_btn, | |
| example_display, | |
| light_env_control_markdown, light_env_idx_input, light_init_btn, light_reset_btn, light_env_info, | |
| energy_env_control_markdown, energy_env_idx_input, energy_init_btn, energy_reset_btn, energy_env_info, | |
| repo_env_control_markdown, repo_env_idx_input, repo_init_btn, repo_reset_btn, repo_env_info, | |
| trade_env_control_markdown, trade_env_idx_input, trade_init_btn, trade_reset_btn, trade_env_info] | |
| ) | |
| task_energy_btn.click( | |
| fn=switch_to_energy, | |
| inputs=[energy_state], | |
| outputs=[energy_state, current_task_type, light_interface, repo_interface, trade_interface, energy_interface, | |
| task_light_btn, task_repo_btn, task_trade_btn, task_energy_btn, | |
| example_display, | |
| light_env_control_markdown, light_env_idx_input, light_init_btn, light_reset_btn, light_env_info, | |
| energy_env_control_markdown, energy_env_idx_input, energy_init_btn, energy_reset_btn, energy_env_info, | |
| repo_env_control_markdown, repo_env_idx_input, repo_init_btn, repo_reset_btn, repo_env_info, | |
| trade_env_control_markdown, trade_env_idx_input, trade_init_btn, trade_reset_btn, trade_env_info] | |
| ) | |
| # ==================== Light Task Event Bindings ==================== | |
| def light_load_wrapper(state, env_idx, user_id): | |
| """Wrapper function for loading Light task environment""" | |
| state, info, state_display, logic, history, progress, steps = light_task.light_load_environment(state, env_idx, user_id, save_dir) | |
| return state, info, state_display, history, steps | |
| light_init_btn.click( | |
| fn=light_load_wrapper, | |
| inputs=[light_state, light_env_idx_input, default_user_id], | |
| outputs=[light_state, light_env_info, light_state_display, light_history_display, light_steps_info_text] | |
| ) | |
| def light_reset_wrapper(state, user_id): | |
| """Wrapper function for resetting Light task environment""" | |
| state, info, state_display, history, progress, steps = light_task.light_reset_environment(state, user_id, save_dir) | |
| return state, info, state_display, history, steps | |
| light_reset_btn.click( | |
| fn=light_reset_wrapper, | |
| inputs=[light_state, default_user_id], | |
| outputs=[light_state, light_env_info, light_state_display, light_history_display, light_steps_info_text] | |
| ) | |
| def light_step_wrapper(state, action_str, user_id): | |
| state, feedback, state_display, history, done, steps_info = light_task.light_step_environment(state, action_str, user_id, save_dir) | |
| test_data = light_task.get_light_test_data(state) | |
| current_env_idx = light_task.get_light_current_env_idx(state) | |
| history_records = light_task.get_light_history_records(state) | |
| if done: | |
| env_info_text = f"๐ Task completed! All lights are on!\nEnvironment Index: {current_env_idx + 1}/{len(test_data) if test_data else 0}" | |
| else: | |
| env_info_text = f"Environment Index: {current_env_idx + 1}/{len(test_data) if test_data else 0}\nSteps: {len(history_records)}" | |
| return state, feedback, state_display, history, env_info_text, steps_info, "" | |
| light_step_btn.click( | |
| fn=light_step_wrapper, | |
| inputs=[light_state, light_action_input, default_user_id], | |
| outputs=[light_state, light_feedback_display, light_state_display, light_history_display, light_env_info, light_steps_info_text, light_action_input] | |
| ) | |
| light_action_input.submit( | |
| fn=light_step_wrapper, | |
| inputs=[light_state, light_action_input, default_user_id], | |
| outputs=[light_state, light_feedback_display, light_state_display, light_history_display, light_env_info, light_steps_info_text, light_action_input] | |
| ) | |
| # ==================== Repo Task Event Bindings ==================== | |
| def repo_load_wrapper(state, env_idx, user_id): | |
| """Wrapper function for loading Repo task environment""" | |
| state, info, state_display, logic, history, progress, steps = repo_task.repo_load_environment(state, env_idx, user_id, save_dir) | |
| return state, info, state_display, history, steps | |
| repo_init_btn.click( | |
| fn=repo_load_wrapper, | |
| inputs=[repo_state, repo_env_idx_input, default_user_id], | |
| outputs=[repo_state, repo_env_info, repo_state_display, repo_history_display, repo_steps_info_text] | |
| ) | |
| def repo_reset_wrapper(state, user_id): | |
| """Wrapper function for resetting Repo task environment""" | |
| state, info, state_display, history, progress, steps = repo_task.repo_reset_environment(state, user_id, save_dir) | |
| return state, info, state_display, history, steps | |
| repo_reset_btn.click( | |
| fn=repo_reset_wrapper, | |
| inputs=[repo_state, default_user_id], | |
| outputs=[repo_state, repo_env_info, repo_state_display, repo_history_display, repo_steps_info_text] | |
| ) | |
| def repo_step_wrapper(state, action_str, user_id): | |
| state, feedback, state_display, history, done, steps_info = repo_task.repo_step_environment(state, action_str, user_id, save_dir) | |
| test_data = repo_task.get_repo_test_data(state) | |
| current_env_idx = repo_task.get_repo_current_env_idx(state) | |
| history_records = repo_task.get_repo_history_records(state) | |
| if done: | |
| env_info_text = f"๐ Task completed! Project runs successfully!\nEnvironment Index: {current_env_idx + 1}/{len(test_data) if test_data else 0}" | |
| else: | |
| env_info_text = f"Environment Index: {current_env_idx + 1}/{len(test_data) if test_data else 0}\nSteps: {len(history_records)}" | |
| return state, feedback, state_display, history, env_info_text, steps_info, "" | |
| repo_step_btn.click( | |
| fn=repo_step_wrapper, | |
| inputs=[repo_state, repo_action_input, default_user_id], | |
| outputs=[repo_state, repo_feedback_display, repo_state_display, repo_history_display, repo_env_info, repo_steps_info_text, repo_action_input] | |
| ) | |
| repo_action_input.submit( | |
| fn=repo_step_wrapper, | |
| inputs=[repo_state, repo_action_input, default_user_id], | |
| outputs=[repo_state, repo_feedback_display, repo_state_display, repo_history_display, repo_env_info, repo_steps_info_text, repo_action_input] | |
| ) | |
| # ==================== Trade Task Event Bindings ==================== | |
| def trade_load_wrapper(state, env_idx, user_id): | |
| """Wrapper function for loading Trade task environment""" | |
| state, info, state_display, logic, history, progress, steps = trade_task.trade_load_environment(state, env_idx, user_id, save_dir) | |
| # Update input boxes based on the number of stocks in the environment | |
| env = trade_task.get_trade_env(state) | |
| if env: | |
| stock_updates = trade_task.get_trade_stock_input_updates(env) | |
| else: | |
| stock_updates = [gr.update(visible=False) for _ in range(10)] | |
| return (state, info, state_display, history, steps) + tuple(stock_updates) | |
| # Collect all 10 stock input boxes (for output updates) | |
| all_trade_stock_inputs = [trade_stock_inputs.get(f"S{i}", None) for i in range(10)] | |
| # Filter out None values | |
| all_trade_stock_inputs = [inp for inp in all_trade_stock_inputs if inp is not None] | |
| trade_init_btn.click( | |
| fn=trade_load_wrapper, | |
| inputs=[trade_state, trade_env_idx_input, default_user_id], | |
| outputs=[trade_state, trade_env_info, trade_state_display, trade_history_display, trade_steps_info_text] + all_trade_stock_inputs | |
| ) | |
| def trade_reset_wrapper(state, user_id): | |
| """Wrapper function for resetting Trade task environment""" | |
| state, info, state_display, history, progress, steps = trade_task.trade_reset_environment(state, user_id, save_dir) | |
| # Update input boxes based on the number of stocks in the environment | |
| env = trade_task.get_trade_env(state) | |
| if env: | |
| stock_updates = trade_task.get_trade_stock_input_updates(env) | |
| else: | |
| stock_updates = [gr.update(visible=False) for _ in range(10)] | |
| return (state, info, state_display, history, steps) + tuple(stock_updates) | |
| trade_reset_btn.click( | |
| fn=trade_reset_wrapper, | |
| inputs=[trade_state, default_user_id], | |
| outputs=[trade_state, trade_env_info, trade_state_display, trade_history_display, trade_steps_info_text] + all_trade_stock_inputs | |
| ) | |
| def trade_step_wrapper(state, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, user_id): | |
| """Wrapper function for executing Trade task actions, collecting data from input boxes (positive for buy, negative for sell)""" | |
| # Dynamically build stock input dictionary using actual stock names from environment | |
| env = trade_task.get_trade_env(state) | |
| stock_inputs = {} | |
| if env: | |
| # Use actual stock names from environment | |
| stock_values = [s0, s1, s2, s3, s4, s5, s6, s7, s8, s9] | |
| for i, stock_name in enumerate(env.stocks): | |
| if i < len(stock_values): | |
| stock_inputs[stock_name] = stock_values[i] or 0 | |
| else: | |
| # If no environment, use default S0-S3 (backward compatibility) | |
| stock_inputs = { | |
| "S0": s0 or 0, | |
| "S1": s1 or 0, | |
| "S2": s2 or 0, | |
| "S3": s3 or 0 | |
| } | |
| state, feedback, state_display, history, done, steps_info = trade_task.trade_step_environment_from_inputs( | |
| state, stock_inputs, user_id, save_dir) | |
| test_data = trade_task.get_trade_test_data(state) | |
| current_env_idx = trade_task.get_trade_current_env_idx(state) | |
| history_records = trade_task.get_trade_history_records(state) | |
| if done: | |
| env_info_text = f"๐ Task completed! All trading days ended!\nEnvironment Index: {current_env_idx + 1}/{len(test_data) if test_data else 0}" | |
| else: | |
| env_info_text = f"Environment Index: {current_env_idx + 1}/{len(test_data) if test_data else 0}\nSteps: {len(history_records)}" | |
| # Clear all input boxes | |
| return (state, feedback, state_display, history, env_info_text, steps_info, | |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | |
| # Collect all 10 input boxes (in order S0-S9) | |
| trade_inputs_list = [trade_stock_inputs.get(f"S{i}", None) for i in range(10)] | |
| # Filter out None values, ensure all input boxes exist | |
| trade_inputs_list = [inp for inp in trade_inputs_list if inp is not None] | |
| trade_step_btn.click( | |
| fn=trade_step_wrapper, | |
| inputs=[trade_state] + trade_inputs_list + [default_user_id], | |
| outputs=[trade_state, trade_feedback_display, trade_state_display, trade_history_display, trade_env_info, trade_steps_info_text] + trade_inputs_list | |
| ) | |
| # ==================== Energy Task Event Bindings ==================== | |
| def energy_load_wrapper(state, env_idx, user_id): | |
| """Wrapper function for loading Energy task environment""" | |
| state, info, state_display, logic, history, progress, steps = energy_task.energy_load_environment(state, env_idx, user_id, save_dir) | |
| cost_text = energy_task.calculate_estimated_cost(state, 0.0, 0.0, 0.0, 0.0) | |
| # Check if environment is completed | |
| env = energy_task.get_energy_env(state) | |
| is_done = env is not None and env.done | |
| return state, info, state_display, history, steps, cost_text, gr.update(interactive=not is_done) | |
| energy_init_btn.click( | |
| fn=energy_load_wrapper, | |
| inputs=[energy_state, energy_env_idx_input, default_user_id], | |
| outputs=[energy_state, energy_env_info, energy_state_display, energy_history_display, energy_steps_info_text, energy_cost_display, energy_step_btn] | |
| ) | |
| def energy_reset_wrapper(state, user_id): | |
| """Wrapper function for resetting Energy task environment""" | |
| state, info, state_display, history, progress, steps = energy_task.energy_reset_environment(state, user_id, save_dir) | |
| cost_text = energy_task.calculate_estimated_cost(state, 0.0, 0.0, 0.0, 0.0) | |
| return state, info, state_display, history, steps, cost_text, gr.update(interactive=True) | |
| energy_reset_btn.click( | |
| fn=energy_reset_wrapper, | |
| inputs=[energy_state, default_user_id], | |
| outputs=[energy_state, energy_env_info, energy_state_display, energy_history_display, energy_steps_info_text, energy_cost_display, energy_step_btn] | |
| ) | |
| def update_energy_cost(state, thermal, wind, solar, battery): | |
| """Update estimated cost in real-time""" | |
| return energy_task.calculate_estimated_cost(state, thermal, wind, solar, battery) | |
| def update_energy_state_display(state, thermal, wind, solar): | |
| """Update state display in real-time, including carbon emission ratio based on input values""" | |
| env = energy_task.get_energy_env(state) | |
| if env is None: | |
| return "Please initialize environment first" | |
| obs = env._get_obs() | |
| return energy_task.format_energy_state(state, obs, thermal_input=thermal, wind_input=wind, solar_input=solar) | |
| # Add change events to all input boxes to update estimated cost and state display in real-time | |
| for input_component in [energy_thermal_input, energy_wind_input, energy_solar_input, energy_battery_input]: | |
| input_component.change( | |
| fn=update_energy_cost, | |
| inputs=[energy_state, energy_thermal_input, energy_wind_input, energy_solar_input, energy_battery_input], | |
| outputs=[energy_cost_display] | |
| ) | |
| # Also update state display (only using thermal, wind, solar, excluding battery) | |
| input_component.change( | |
| fn=update_energy_state_display, | |
| inputs=[energy_state, energy_thermal_input, energy_wind_input, energy_solar_input], | |
| outputs=[energy_state_display] | |
| ) | |
| def energy_step_wrapper(state, thermal, wind, solar, battery, user_id): | |
| """Wrapper function for executing Energy task actions, collecting data from input boxes""" | |
| state, feedback, state_display, history, done, steps_info = energy_task.energy_step_environment_from_inputs( | |
| state, thermal, wind, solar, battery, user_id, save_dir) | |
| test_data = energy_task.get_energy_test_data(state) | |
| current_env_idx = energy_task.get_energy_current_env_idx(state) | |
| history_records = energy_task.get_energy_history_records(state) | |
| current_steps = len(history_records) | |
| if done: | |
| if current_steps < energy_task.ENERGY_MAX_STEPS: | |
| env_info_text = f"โ Task failed (completed)\nEnvironment Index: {current_env_idx + 1}/{len(test_data) if test_data else 0}\nSteps: {current_steps} / {energy_task.ENERGY_MAX_STEPS}" | |
| else: | |
| env_info_text = f"๐ Task completed!\nEnvironment Index: {current_env_idx + 1}/{len(test_data) if test_data else 0}\nSteps: {current_steps} / {energy_task.ENERGY_MAX_STEPS}" | |
| else: | |
| env_info_text = f"Environment Index: {current_env_idx + 1}/{len(test_data) if test_data else 0}\nSteps: {len(history_records)}" | |
| # Clear input boxes and update estimated cost | |
| cost_text = energy_task.calculate_estimated_cost(state, 0.0, 0.0, 0.0, 0.0) | |
| return (state, feedback, state_display, history, env_info_text, steps_info, | |
| 0.0, 0.0, 0.0, 0.0, cost_text, gr.update(interactive=not done)) | |
| energy_step_btn.click( | |
| fn=energy_step_wrapper, | |
| inputs=[energy_state, energy_thermal_input, energy_wind_input, energy_solar_input, energy_battery_input, default_user_id], | |
| outputs=[energy_state, energy_feedback_display, energy_state_display, energy_history_display, energy_env_info, energy_steps_info_text, | |
| energy_thermal_input, energy_wind_input, energy_solar_input, energy_battery_input, energy_cost_display, energy_step_btn] | |
| ) | |
| # ==================== Initialization ==================== | |
| # Automatically load test data for default task (Light) when page loads | |
| def init_light_data(state): | |
| state, _ = light_task.load_light_test_data(state, current_dir) | |
| return state | |
| demo.load( | |
| fn=init_light_data, | |
| inputs=[light_state], | |
| outputs=[light_state] | |
| ) | |
| return demo | |
| # ------------------- Main Function ------------------- | |
| if __name__ == "__main__": | |
| demo = create_interface() | |
| if os.getenv("SPACE_ID") is None: | |
| demo.launch( | |
| server_name="127.0.0.1", | |
| server_port=7860, | |
| share=False, | |
| theme=gr.themes.Soft() | |
| ) | |
| else: | |
| demo.launch(theme=gr.themes.Soft()) | |