umar141's picture
Pure code deploy - no binaries
c415c9a
Raw
History Blame Contribute Delete
8.62 kB
import json
import os
import gradio as gr
from gradio.components import Component
from typing import Any, Dict, Optional
from src.webui.webui_manager import WebuiManager
from src.utils import config
import logging
from distutils.util import strtobool
from functools import partial
logger = logging.getLogger(__name__)
def update_model_dropdown(llm_provider, model_type="main"):
model_dict = config.main_models if model_type == "main" else config.planning_models
if llm_provider in model_dict:
return gr.Dropdown(choices=model_dict[llm_provider], value=model_dict[llm_provider][0], interactive=True)
else:
return gr.Dropdown(choices=[], value="", interactive=True, allow_custom_value=True)
async def update_mcp_server(mcp_file: str, webui_manager: WebuiManager):
if hasattr(webui_manager, "bu_controller") and webui_manager.bu_controller:
await webui_manager.bu_controller.close_mcp_client()
webui_manager.bu_controller = None
if not mcp_file or not os.path.exists(mcp_file) or not mcp_file.endswith('.json'):
return None, gr.update(visible=False)
with open(mcp_file, 'r') as f:
mcp_server = json.load(f)
return json.dumps(mcp_server, indent=2), gr.update(visible=True)
async def close_browser_resources(webui_manager: WebuiManager):
if webui_manager.bu_current_task and not webui_manager.bu_current_task.done():
webui_manager.bu_current_task.cancel()
webui_manager.bu_current_task = None
if webui_manager.bu_browser_context:
await webui_manager.bu_browser_context.close()
webui_manager.bu_browser_context = None
if webui_manager.bu_browser:
await webui_manager.bu_browser.close()
webui_manager.bu_browser = None
def create_settings_tab(webui_manager: WebuiManager):
agent_tab_components = {}
browser_tab_components = {}
default_provider = os.getenv("DEFAULT_LLM", "openai")
if default_provider not in config.main_models:
default_provider = "openai"
with gr.Accordion("🤖 LLM & Agent Configuration", open=True):
with gr.Row():
llm_provider = gr.Dropdown(choices=list(config.main_models.keys()), label="LLM Provider", value=default_provider, interactive=True)
llm_model_name = gr.Dropdown(label="LLM Model Name", choices=config.main_models[default_provider], value=config.main_models[default_provider][0], interactive=True, allow_custom_value=True)
with gr.Row():
llm_temperature = gr.Slider(minimum=0.0, maximum=2.0, value=0.6, step=0.1, label="Temperature", interactive=True)
use_vision = gr.Checkbox(label="Use Vision", value=True, interactive=True)
ollama_num_ctx = gr.Slider(minimum=256, maximum=65536, value=16000, step=1, label="Ollama Context Length", visible=False, interactive=True)
with gr.Row():
llm_base_url = gr.Textbox(label="Base URL", value="", placeholder="Optional API endpoint")
llm_api_key = gr.Textbox(label="API Key", type="password", value="", placeholder="Leave blank to use .env")
with gr.Accordion("📋 System Prompt & Memory", open=False):
override_system_prompt = gr.Textbox(label="Override system prompt", lines=3, interactive=True)
extend_system_prompt = gr.Textbox(label="Extend system prompt", lines=3, interactive=True)
with gr.Accordion("🧠 Planner LLM Configuration", open=False):
with gr.Row():
planner_llm_provider = gr.Dropdown(choices=list(config.planning_models.keys()), label="Planner Provider", value=None, interactive=True)
planner_llm_model_name = gr.Dropdown(label="Planner Model Name", interactive=True, allow_custom_value=True)
with gr.Row():
planner_llm_temperature = gr.Slider(minimum=0.0, maximum=2.0, value=0.6, step=0.1, label="Planner Temp", interactive=True)
planner_use_vision = gr.Checkbox(label="Planner Vision", value=False, interactive=True)
with gr.Row():
planner_llm_base_url = gr.Textbox(label="Planner Base URL", value="")
planner_llm_api_key = gr.Textbox(label="Planner API Key", type="password", value="")
with gr.Accordion("🌐 Browser Configuration", open=False):
with gr.Row():
use_own_browser = gr.Checkbox(label="Use Own Browser", value=bool(strtobool(os.getenv("USE_OWN_BROWSER", "false"))), interactive=True)
keep_browser_open = gr.Checkbox(label="Keep Browser Open", value=bool(strtobool(os.getenv("KEEP_BROWSER_OPEN", "true"))), interactive=True)
headless = gr.Checkbox(label="Headless Mode", value=False, interactive=True)
disable_security = gr.Checkbox(label="Disable Security", value=False, interactive=True)
with gr.Row():
window_w = gr.Number(label="Width", value=1280, interactive=True)
window_h = gr.Number(label="Height", value=1100, interactive=True)
with gr.Row():
browser_binary_path = gr.Textbox(label="Browser Binary Path", placeholder="Path to Chrome/Edge binary")
browser_user_data_dir = gr.Textbox(label="User Data Dir", placeholder="Custom profile path")
with gr.Accordion("🛠️ Advanced Settings", open=False):
with gr.Row():
max_steps = gr.Slider(minimum=1, maximum=1000, value=100, step=1, label="Max Steps")
max_actions = gr.Slider(minimum=1, maximum=100, value=10, step=1, label="Max Actions/Step")
with gr.Row():
max_input_tokens = gr.Number(label="Max Input Tokens", value=128000, precision=0)
tool_calling_method = gr.Dropdown(label="Tool Calling", value="auto", choices=['function_calling', 'json_mode', 'raw', 'auto', 'tools', "None"])
with gr.Row():
mcp_json_file = gr.File(label="MCP Config (.json)", file_types=[".json"])
mcp_server_config = gr.Textbox(label="MCP JSON", lines=4, visible=False)
# --- Navigation Logic ---
def update_model_dropdown(provider, type="main"):
models = config.main_models if type == "main" else config.planning_models
return gr.update(choices=models.get(provider, []), value=models.get(provider, [""])[0])
# Register components to manager using legacy prefixes to keep compatibility with agents
# Split them into agent_settings and browser_settings categories
legacy_agent_settings = {
"llm_provider": llm_provider, "llm_model_name": llm_model_name, "llm_temperature": llm_temperature,
"use_vision": use_vision, "ollama_num_ctx": ollama_num_ctx, "llm_base_url": llm_base_url, "llm_api_key": llm_api_key,
"override_system_prompt": override_system_prompt, "extend_system_prompt": extend_system_prompt,
"planner_llm_provider": planner_llm_provider, "planner_llm_model_name": planner_llm_model_name,
"planner_llm_temperature": planner_llm_temperature, "planner_use_vision": planner_use_vision,
"planner_llm_base_url": planner_llm_base_url, "planner_llm_api_key": planner_llm_api_key,
"max_steps": max_steps, "max_actions": max_actions, "max_input_tokens": max_input_tokens,
"tool_calling_method": tool_calling_method, "mcp_json_file": mcp_json_file, "mcp_server_config": mcp_server_config
}
legacy_browser_settings = {
"use_own_browser": use_own_browser, "keep_browser_open": keep_browser_open, "headless": headless,
"disable_security": disable_security, "window_w": window_w, "window_h": window_h,
"browser_binary_path": browser_binary_path, "browser_user_data_dir": browser_user_data_dir
}
webui_manager.add_components("agent_settings", legacy_agent_settings)
webui_manager.add_components("browser_settings", legacy_browser_settings)
# Handlers
llm_provider.change(lambda x: gr.update(visible=x == "ollama"), inputs=llm_provider, outputs=ollama_num_ctx)
llm_provider.change(lambda p: update_model_dropdown(p, "main"), inputs=[llm_provider], outputs=[llm_model_name])
planner_llm_provider.change(lambda p: update_model_dropdown(p, "planning"), inputs=[planner_llm_provider], outputs=[planner_llm_model_name])
async def mcp_wrapper(f): return await update_mcp_server(f, webui_manager)
mcp_json_file.change(fn=mcp_wrapper, inputs=[mcp_json_file], outputs=[mcp_server_config, mcp_server_config])
async def resource_close_wrapper(): await close_browser_resources(webui_manager)
for comp in [headless, keep_browser_open, disable_security, use_own_browser]:
comp.change(resource_close_wrapper)
return legacy_agent_settings, legacy_browser_settings