Source code for mailos.ui.checker_form

"""UI functions for creating and editing checker forms."""

from pywebio.output import close_popup, popup, put_buttons, put_markdown, use_scope
from pywebio.pin import (
    pin,
    pin_on_change,
    put_checkbox,
    put_input,
    put_select,
    put_textarea,
)

from mailos.tools import AVAILABLE_TOOLS
from mailos.utils.config_utils import load_config
from mailos.utils.logger_utils import logger
from mailos.vendors.config import VENDOR_CONFIGS
from mailos.vendors.factory import LLMFactory


[docs] def create_checker_form(checker_id=None, on_save=None): """Create a form for new checker or editing existing one. Args: checker_id: The ID of the checker to edit, or None for new checker on_save: Callback function to save the checker """ config = load_config() checker = None if checker_id: # Find checker by ID for c in config["checkers"]: if c.get("id") == checker_id: checker = c break if not checker: logger.warning(f"No checker found with ID: {checker_id}") return else: checker = {} llm_providers = list(LLMFactory._providers.keys()) # Log the current state logger.debug(f"Creating form for checker ID: {checker_id}") logger.debug(f"Current checker config: {checker}") # Pre-select current features current_features = [] if checker.get("enabled", False): current_features.append("Enable monitoring") if checker.get("auto_reply", False): current_features.append("Auto-reply to emails") # Get currently enabled tools current_tools = checker.get("enabled_tools", []) def submit_form(): # Log form data before submission logger.debug("Form submission - Collecting pin data:") logger.debug(f"checker_name: {pin.checker_name}") logger.debug(f"monitor_email: {pin.monitor_email}") logger.debug(f"imap_server: {pin.imap_server}") logger.debug(f"imap_port: {pin.imap_port}") logger.debug(f"features: {pin.features}") logger.debug(f"enabled_tools: {pin.enabled_tools}") if on_save: on_save(checker_id) close_popup() with popup(f"{'Edit' if checker_id else 'New'} Email Checker", size="large"): put_markdown(f"### {'Edit' if checker_id else 'New'} Email Checker") # Email configuration fields put_input( "checker_name", type="text", label="Checker Name", value=checker.get("name", ""), ) put_input( "monitor_email", type="text", label="Email to monitor", value=checker.get("monitor_email", ""), ) put_input( "password", type="password", label="Email password", value=checker.get("password", ""), ) # Log current IMAP server value before creating input logger.debug( "Setting IMAP server input with value: %s", checker.get("imap_server", "imap.gmail.com"), ) put_input( "imap_server", type="text", label="IMAP Server", value=checker.get("imap_server", "imap.gmail.com"), ) put_input( "imap_port", type="number", label="IMAP Port", value=checker.get("imap_port", 993), ) put_checkbox( "features", options=["Enable monitoring", "Auto-reply to emails"], value=current_features, inline=True, ) # Tools selection put_markdown("### Available Tools") put_checkbox( "enabled_tools", options=[ {"label": display_name, "value": tool_name} for tool_name, display_name in AVAILABLE_TOOLS ], value=current_tools, inline=True, help_text="Select tools to enable for this checker", ) # LLM configuration put_markdown("### LLM Configuration") put_select( "llm_provider", options=llm_providers, label="LLM Provider", value=checker.get("llm_provider", llm_providers[0]), ) def on_provider_change(provider): vendor_config = VENDOR_CONFIGS.get(provider) if not vendor_config: return with use_scope("provider_credentials", clear=True): # Add model selection with supported models put_select( "model", options=vendor_config.supported_models, label="Model Name", value=checker.get("model", vendor_config.default_model), ) # Add vendor-specific configuration fields for field in vendor_config.fields: put_input( field.name, type=field.type, label=field.label, value=checker.get(field.name, field.default or ""), help_text=field.help_text, ) # Initial credentials fields with use_scope("provider_credentials"): on_provider_change(checker.get("llm_provider", llm_providers[0])) put_textarea( "system_prompt", label="System Prompt", value=checker.get("system_prompt", ""), rows=5, ) put_buttons( [ {"label": "Save", "value": "save", "color": "success"}, {"label": "Cancel", "value": "cancel", "color": "secondary"}, ], onclick=lambda val: submit_form() if val == "save" else close_popup(), ) # Register provider change handler pin_on_change("llm_provider", onchange=on_provider_change)