diff --git a/.gitignore b/.gitignore index 2d83410..a3f269d 100644 --- a/.gitignore +++ b/.gitignore @@ -184,3 +184,6 @@ AgentHistoryList.json # For Docker data/ + +# For Config Files (Current Settings) +.config.pkl diff --git a/src/utils/utils.py b/src/utils/utils.py index 3ab3897..c388742 100644 --- a/src/utils/utils.py +++ b/src/utils/utils.py @@ -6,6 +6,7 @@ # @FileName: utils.py import base64 import os +import pickle import time from pathlib import Path from typing import Dict, Optional @@ -201,3 +202,13 @@ async def capture_screenshot(browser_context): return encoded except Exception as e: return None + +def load_config_from_file(file_path: str='./.config.pkl',): + with open(file_path, 'rb') as file: + loaded_person = pickle.load(file) + return loaded_person + + +def save_config_to_file(config, file_path: str='./.config.pkl',) -> None: + with open(file_path, 'wb') as file: + pickle.dump(config, file) diff --git a/webui.py b/webui.py index b7acffe..7c9fce6 100644 --- a/webui.py +++ b/webui.py @@ -39,7 +39,7 @@ from src.browser.custom_context import BrowserContextConfig, CustomBrowserContext from src.controller.custom_controller import CustomController from gradio.themes import Citrus, Default, Glass, Monochrome, Ocean, Origin, Soft, Base -from src.utils.utils import update_model_dropdown, get_latest_files, capture_screenshot +from src.utils.utils import load_config_from_file, save_config_to_file, update_model_dropdown, get_latest_files, capture_screenshot from dotenv import load_dotenv load_dotenv() @@ -422,6 +422,7 @@ async def run_with_stream( max_actions_per_step, tool_call_in_content ): + save_config_to_file(locals()) global _global_agent_state stream_vw = 80 stream_vh = int(80 * window_h // window_w) @@ -565,6 +566,11 @@ async def run_with_stream( gr.update(interactive=True) # Re-enable run button ] +async def load_and_run_with_stream(): + config = load_config_from_file() + async for output in run_with_stream(**config): + yield output + # Define the theme map globally theme_map = { "Default": Default(), @@ -663,6 +669,19 @@ def create_ui(theme_name="Ocean"): value=True, info="Enable Tool Calls in content", ) + load_config_button = gr.Button("🔄 Load Saved Config") + config_preview = gr.Textbox( + label="Loaded Configuration", + value="", + lines=10, + interactive=False + ) + + load_config_button.click( + fn=lambda: str(load_config_from_file()), + inputs=[], + outputs=config_preview + ) with gr.TabItem("🔧 LLM Configuration", id=2): with gr.Group(): @@ -781,6 +800,8 @@ def create_ui(theme_name="Ocean"): info="Optional hints to help the LLM complete the task", ) + load_button = gr.Button("💾 Load & Run Config", variant="secondary", scale=1) + with gr.Row(): run_button = gr.Button("â–ļī¸ Run Agent", variant="primary", scale=2) stop_button = gr.Button("⏚ī¸ Stop", variant="stop", scale=1) @@ -850,6 +871,23 @@ def create_ui(theme_name="Ocean"): ], ) + load_button.click( + fn=load_and_run_with_stream, + inputs=[], + outputs=[ + browser_view, + final_result_output, + errors_output, + model_actions_output, + model_thoughts_output, + recording_display, + trace_file, + agent_history_file, + stop_button, + run_button + ], + ) + with gr.TabItem("đŸŽĨ Recordings", id=6): def list_recordings(save_recording_path): if not os.path.exists(save_recording_path):