# # SPDX-FileCopyrightText: Hadad # SPDX-License-Identifier: Apache-2.0 # import logging # Import the logging module to enable tracking of events, errors, and debugging information during program execution import warnings # Import the warnings module to manage and control warning messages generated by the code or libraries import os # Import the os module to interact with the operating system, such as file system operations and environment variables import sys # Import the sys module to access system-specific parameters and functions, including command-line arguments and interpreter information import gradio as gr # Import the Gradio library to build interactive web interfaces for machine learning applications, enabling easy deployment and testing from src.core.parameter import parameters # Import the 'parameters' function from the core parameter module, which provides model parameter configurations based on the selected reasoning mode from src.client.chat_handler import respond # Import the 'respond' function from the chat handler module, responsible for generating AI assistant responses to user inputs from config import model, meta_tags # Import 'model' dictionary containing available model precision options and their details, and 'meta_tags' dictionary containing HTML meta tag information for web interface setup # Define the main user interface function for the Gradio application def ui(): """ This function constructs and configures the entire user interface for the AI assistant web application using the Gradio Blocks API. The function is responsible for setting up logging and warning filters, suppressing unwanted output, and building a highly interactive sidebar for model configuration. It provides users with a comprehensive set of controls to adjust model precision, reasoning mode, and advanced generation parameters such as temperature, top_k, min_p, top_p, and repetition penalty. The sidebar also allows users to enable or disable additional features like image generation, audio generation, and deep web search, each with descriptive tooltips to guide user interaction. The function dynamically updates parameter sliders based on the state of the reasoning checkbox, ensuring that the UI always reflects the current configuration. The main chat interface is constructed with a set of example prompts to help users explore the assistant's capabilities, and all configuration states are passed as additional inputs to the response handler. Output and error streams are redirected to prevent extraneous log messages from appearing in the web interface, creating a clean and focused user experience. The function returns the fully constructed Gradio app object, ready to be launched or embedded as needed. This approach ensures the application is robust, user-friendly, and highly customizable, making it suitable for both demonstration and production use """ # Suppress all warning messages globally to prevent them from displaying in the application output and confusing users warnings.filterwarnings( "ignore" # Specify the action to ignore all warnings, ensuring a clean user interface free from warning clutter ) # Set the warnings filter to ignore warnings by default, providing an additional layer of suppression for any warnings that might arise during runtime warnings.simplefilter( "ignore" # Apply the ignore filter to all warning categories, further ensuring that no warnings are shown to users ) # Configure the logging system to only display messages at the CRITICAL level or higher, effectively hiding informational, warning, and error logs from the application's output logging.basicConfig( level=logging.CRITICAL # Set the logging threshold to CRITICAL, which is the highest severity level, to minimize log output ) # Define a list of logger names associated with common web and async frameworks used in Gradio apps logger_keywords = [ "uvicorn", # Uvicorn is an ASGI web server commonly used with FastAPI and Gradio "fastapi", # FastAPI is a modern web framework for building APIs with Python "gradio", # Gradio's own logger, which may emit internal messages "httpx", # HTTPX is an HTTP client for Python, often used for making web requests "aiohttp", # Aiohttp is an asynchronous HTTP client and server library "asyncio", # Asyncio is Python's standard library for asynchronous programming "starlette", # Starlette is a lightweight ASGI framework used by FastAPI "anyio", # AnyIO is an asynchronous networking and concurrency library ] # Iterate through all registered loggers in the logging system to suppress their output if they match any of the specified keywords for name, logger in logging.root.manager.loggerDict.items(): # Check if the logger's name contains any of the keywords from the list, indicating it is associated with a third-party library whose logs should be suppressed if any(k in name for k in logger_keywords): # Ensure the logger object is an instance of the Logger class before attempting to set its level if isinstance( logger, # The logger object retrieved from the logger dictionary logging.Logger # The Logger class from the logging module ): # Set the logger's level to CRITICAL to prevent it from emitting lower-severity log messages during application execution logger.setLevel( logging.CRITICAL # Only allow critical errors to be logged, hiding all informational and warning messages ) # Redirect the standard output stream to the null device, effectively silencing all print statements and unwanted output from third-party libraries sys.stdout = open( os.devnull, "w" # Open the operating system's null device in write mode, discarding any data written to it ) # Redirect the standard error stream to the null device, ensuring that error messages and tracebacks do not appear in the application's output sys.stderr = open( os.devnull, "w" # Open the null device for error output, suppressing all error messages from being displayed to users ) # Create the main Gradio Blocks application, which serves as the container for all UI components and layout with gr.Blocks( fill_height=True, # Automatically adjust the block's height to fill the available vertical space in the browser window, ensuring a responsive design fill_width=True, # Automatically adjust the block's width to fill the available horizontal space, maximizing the use of screen real estate head=meta_tags # Inject custom meta tags into the HTML head section, allowing for SEO optimization ) as app: """ This code block initializes the main Gradio Blocks context, which acts as the root container for all user interface components in the application. The fill_height and fill_width parameters ensure that the app dynamically resizes to fit the user's browser window, providing a seamless and visually appealing experience. The head parameter inserts custom meta tags into the HTML head, enabling advanced customization such as setting the page title, description, favicon, or viewport settings. All UI elements, including the sidebar configuration controls and the main chat interface, are defined within this context to ensure they are properly managed and rendered by Gradio. The resulting 'app' object encapsulates the entire interactive application, making it easy to launch or embed as needed """ # Begin the sidebar section, which slides in from the left and contains all model configuration controls. The sidebar starts in a closed state for a cleaner initial appearance with gr.Sidebar(open=False): # Create a dropdown menu that allows users to select the desired model precision from the available options defined in the 'model' dictionary model_precision = gr.Dropdown( choices=list(model.keys()), # Populate the dropdown with the keys from the model dictionary, such as "F16", "F32", or custom precision names label="Model Precision", # Display this label above the dropdown to clearly indicate its purpose to users info=( # Provide a tooltip that explains the impact of different precision settings on model speed and accuracy, helping users make informed choices "The smaller the value, the faster the response but less accurate. " "Conversely, the larger the value, the response is slower but more accurate." ), value="Q8_K_XL" # Set the default selected value to "Q8_K_XL", which represents a specific model precision configuration ) # Add a checkbox that enables or disables reasoning mode, which affects how the AI assistant processes user queries and generates responses reasoning = gr.Checkbox( label="Reasoning", # Show this label next to the checkbox to indicate its function info="Switching between thinking and non-thinking mode.", # Display a tooltip explaining that this option toggles the AI's ability to perform complex reasoning value=True # Set the default state to enabled, so the AI uses reasoning mode by default ) # Create a slider for the 'Temperature' parameter, which controls the randomness of the AI's text generation. The slider is initially non-interactive and updated dynamically based on reasoning mode temperature = gr.Slider( minimum=0.0, # Allow the temperature value to range from 0.0, representing deterministic output maximum=2.0, # Set the upper limit to 2.0, allowing for highly random and creative responses step=0.01, # Allow fine-grained adjustments in increments of 0.01 for precise control label="Temperature", # Label the slider so users know what parameter they are adjusting interactive=False # Disable direct user interaction, as the value is set programmatically when reasoning mode changes ) # Add a slider for the 'Top K' parameter, which limits the number of highest-probability tokens considered during text generation. This helps control output diversity top_k = gr.Slider( minimum=0, # Allow the top_k value to start at 0, which may disable the filter maximum=100, # Set the maximum to 100, providing a wide range for experimentation with model output diversity step=1, # Adjust the value in whole number increments for clarity label="Top K", # Label the slider for user understanding interactive=False # Make the slider non-interactive, as it is updated based on reasoning mode ) # Create a slider for the 'Min P' parameter, representing the minimum cumulative probability threshold for token selection during generation min_p = gr.Slider( minimum=0.0, # Allow the minimum probability to start at 0.0, including all tokens maximum=1.0, # Set the maximum to 1.0, representing the full probability mass step=0.01, # Use small increments for precise tuning label="Min P", # Label the slider to clarify its function interactive=False # Disable direct interaction, as it is controlled programmatically ) # Add a slider for the 'Top P' parameter, which controls nucleus sampling by limiting the cumulative probability of selected tokens top_p = gr.Slider( minimum=0.0, # Allow the top_p value to start at 0.0, which may restrict output to only the most probable token maximum=1.0, # Set the upper limit to 1.0, including all tokens in the sampling pool step=0.01, # Enable fine adjustments for optimal output control label="Top P", # Label the slider accordingly interactive=False # Make the slider non-interactive, as it is set based on reasoning mode ) # Create a slider for the 'Repetition Penalty' parameter, which discourages the model from generating repetitive text by penalizing repeated tokens repetition_penalty = gr.Slider( minimum=0.1, # Set the minimum penalty to 0.1, allowing for low but non-zero penalties maximum=2.0, # Allow penalties up to 2.0, strongly discouraging repetition step=0.01, # Use small increments for precise adjustment label="Repetition Penalty", # Label the slider for clarity interactive=False # Make the slider non-interactive, as it is updated programmatically ) # Define a function to update all parameter sliders when the reasoning checkbox is toggled by the user def update_parameters(switching): """ This function is triggered whenever the user changes the state of the reasoning checkbox in the sidebar. It calls the 'parameters' function, passing the new reasoning state, to retrieve a tuple of updated values for temperature, top_k, min_p, top_p, and repetition penalty. The returned values are then used to update the corresponding sliders in the sidebar, ensuring that the UI always reflects the current configuration for the selected reasoning mode. This dynamic updating mechanism provides immediate feedback to users and helps prevent configuration mismatches, improving the overall user experience and reliability of the application """ # Call the external 'parameters' function with the current reasoning state to get updated parameter values return parameters(switching) # Set up an event listener that calls 'update_parameters' whenever the reasoning checkbox state changes, updating all related sliders with new values reasoning.change( fn=update_parameters, # Specify the function to call when the checkbox value changes inputs=[reasoning], # Pass the current value of the reasoning checkbox as input outputs=[temperature, top_k, min_p, top_p, repetition_penalty], # Update all relevant sliders with the new parameter values api_name=False # Disable API exposure for this event, as it is only used internally by the UI ) # Initialize all parameter sliders with values corresponding to the default state of the reasoning checkbox, ensuring the UI is consistent on first load values = parameters(reasoning.value) temperature.value, top_k.value, min_p.value, top_p.value, repetition_penalty.value = values # Add a checkbox to enable or disable image generation capabilities in the chat interface, allowing users to control access to this feature image_generation = gr.Checkbox( label="Image Generation", # Display this label next to the checkbox for clarity info=( # Provide a tooltip explaining how to trigger image generation using a special chat command "Type /image followed by the instructions to start generating an image." ), value=True # Enable image generation by default for user convenience ) # Add a checkbox to enable or disable audio generation in the chat, giving users control over this feature audio_generation = gr.Checkbox( label="Audio Generation", # Label the checkbox for clarity info=( # Tooltip instructing users to use the /audio command to generate audio responses "Type /audio followed by the instructions to start generating audio." ), value=True # Enable audio generation by default ) # Add a checkbox to enable or disable deep web search functionality in the chat interface search_generation = gr.Checkbox( label="Deep Search", # Label the checkbox to indicate its purpose info=( # Tooltip explaining how to trigger deep search using the /dp command in chat "Type /dp followed by the instructions to search the web." ), value=True # Enable deep search by default ) # Create the main chat interface where users can interact with the AI assistant, send messages, and receive responses gr.ChatInterface( fn=respond, # Specify the function that processes user input and generates assistant responses # Provide a list of additional input components whose current values are passed to the respond function for each user message additional_inputs=[ model_precision, # Current selected model precision value from the dropdown temperature, # Current temperature value from the slider top_k, # Current top_k value from the slider min_p, # Current min_p value from the slider top_p, # Current top_p value from the slider repetition_penalty, # Current repetition penalty value from the slider reasoning, # Current state of the reasoning checkbox image_generation, # Whether image generation is enabled audio_generation, # Whether audio generation is enabled search_generation # Whether deep search is enabled ], # Provide a list of example prompts that users can click to quickly test the assistant's capabilities and explore different features examples=[ ["Please introduce yourself."], ["/audio Could you explain what Artificial Intelligence (AI) is?"], ["/audio What is Hugging Face?"], ["/dp Please search for the J.A.R.V.I.S. AI model on Hugging Face."], ["/dp What is the capital city of Indonesia?"], ["/image Create an image of a futuristic city."], ["/image Create a cartoon-style image of a man."], ["What day is it today, what's the date, and what time is it?"], ['/audio Say "I am J.A.R.V.I.S.".'], ["How can I run you in the terminal without having to download the model?"], ["Do you have an OpenAI-compatible API for your model?"], ["Please generate a highly complex code snippet on any topic."], ["Explain about quantum computers."] ], cache_examples=False, # Disable caching of example outputs to ensure fresh responses are generated each time an example is selected chatbot=gr.Chatbot( label="J.A.R.V.I.S.", # Set the title label above the chat window to "J.A.R.V.I.S." for branding and recognition show_copy_button=True, # Display a button that allows users to easily copy chat messages for later use scale=1, # Set the scale factor for the chatbot UI, keeping the default size allow_tags=["think"] # Allow the use of the "think" tag to indicate reasoning mode in chat ), multimodal=False, # Disable file upload capabilities, restricting the chat to text-only interactions api_name="api", # Expose the chat interface as an API endpoint named "api" for programmatic access if needed ) # Return the fully constructed Gradio app object, which can be launched as a standalone web application or embedded in other platforms return app