import gradio as gr import logging import uuid from datetime import datetime import pandas as pd from i18n import get_text from model_handler import ModelHandler from tab_chat import create_chat_tab, get_history_df, on_app_load from tab_chat import update_language as update_chat_language from tab_code import create_code_tab from tab_code import update_language as update_code_language from tab_smart_writer import create_smart_writer_tab from tab_smart_writer import update_language as update_writer_language from tab_welcome import create_welcome_tab from tab_welcome import update_language as update_welcome_language # Configure logging logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) logger = logging.getLogger(__name__) CSS = """ #chatbot { height: calc(100vh - 21px - 16px); max-height: 1500px; } footer { display: none !important; } /* Disable transition and animation for no-transition class */ .no-transition, .no_transition * { transition: none !important; animation: none !important; animation-play-state: paused !important; } .welcome-content { min-width: 240px; max-width: 800px; padding: 20px; margin-left: auto; margin-right: auto; align-items: center; } .language-buttons { gap: 10px; /* Space between buttons */ align-items: center; /* Center buttons within their column */ } .language-buttons > button { width: 240px; /* Example fixed width for buttons */ } """ if __name__ == "__main__": # Instantiate the model handler with the configuration logger.info("Starting Ling Space Application...") model_handler = ModelHandler() with gr.Blocks(analytics_enabled=False, fill_height=True, fill_width=True) as demo: # Language State current_lang_state = gr.State("en") # --- Collect all components that need language updates --- all_i18n_outputs = [] with gr.Tabs(elem_id="indicator-space-app") as tabs: welcome_components = create_welcome_tab(current_lang_state.value, tabs) # The order of components MUST be consistent welcome_outputs = [ welcome_components["tab"], welcome_components["header"], welcome_components["description"], welcome_components["chat_description"], welcome_components["code_description"], welcome_components["writer_description"], welcome_components["model_links_header"], welcome_components["hf_link"], welcome_components["hf_report"], welcome_components["x_account"], welcome_components["lang_select_header"], welcome_components["en_button"], welcome_components["zh_button"], ] all_i18n_outputs.extend(welcome_outputs) # --- Chat Tab --- with gr.TabItem( get_text("chat_tab_title", current_lang_state.value), id="chat" ) as chat_tab: chat_components = create_chat_tab( current_lang_state.value, current_lang_state ) chat_outputs = [ chat_tab, chat_components["new_chat_btn"], chat_components["history_df"], chat_components["chatbot"], chat_components["textbox"], chat_components["submit_btn"], chat_components["recommended_title"], chat_components["recommended_dataset"], chat_components["system_prompt_textbox"], chat_components["temperature_slider"], ] all_i18n_outputs.extend(chat_outputs) chat_tab.select( fn=None, js="() => {window.dispatchEvent(new CustomEvent('tabSelect.chat')); return null;}", ) # --- Code Tab --- with gr.TabItem( get_text("code_tab_title", current_lang_state.value), id="code" ) as code_tab: code_components = create_code_tab( current_lang_state.value, current_lang_state ) code_outputs = [ code_tab, code_components["prompt_input"], code_components["overall_style_input"], code_components["decoration_input"], code_components["palette_display"], code_components["generate_style_btn"], code_components["examples_title"], code_components["examples_dataset"], code_components["generate_button"], code_components["preview_tab"], code_components["preview_header"], code_components["source_code_tab"], code_components["source_code_header"], code_components["code_output"], code_components["refresh_button"], code_components["log_chatbot"], code_components["js_error_channel"], # fullscreen_button is updated in its own handler, so it's excluded here ] all_i18n_outputs.extend(code_outputs) code_tab.select( fn=None, js="() => {window.dispatchEvent(new CustomEvent('tabSelect.code')); return null;}", ) # --- Writer Tab --- with gr.TabItem( get_text("writer_tab_title", current_lang_state.value), id="writer" ) as writer_tab: writer_components = create_smart_writer_tab(current_lang_state) writer_outputs = [ writer_tab, writer_components["style_input"], writer_components["kb_accordion"], writer_components["kb_input"], writer_components["btn_suggest_kb"], writer_components["suggested_kb_dataframe"], writer_components["short_outline_accordion"], writer_components["short_outline_input"], writer_components["btn_sync_outline"], writer_components["long_outline_accordion"], writer_components["long_outline_input"], writer_components["flow_suggestion_display"], writer_components["btn_accept_flow"], writer_components["btn_change_flow"], writer_components["inspiration_prompt_input"], writer_components["prompt_suggestions_dataset"], writer_components["refresh_suggestions_btn"], writer_components["btn_generate_para"], writer_components["btn_change_para"], writer_components["btn_accept_para"], writer_components["para_suggestion_display"], writer_components["polish_title"], writer_components["polish_soon"], writer_components["stats_display"], writer_components["editor"], ] all_i18n_outputs.extend(writer_outputs) writer_tab.select( fn=None, js="() => {window.dispatchEvent(new CustomEvent('tabSelect.writing')); return null;}", ) # --- Language Change Handler --- def on_language_change(lang): # Dispatch updates for each tab welcome_updates = update_welcome_language(lang, welcome_components) chat_updates = update_chat_language(lang, chat_components) chat_updates[chat_tab] = gr.update(label=get_text("chat_tab_title", lang)) code_updates = update_code_language(lang, code_components) code_updates[code_tab] = gr.update(label=get_text("code_tab_title", lang)) writer_updates = update_writer_language(lang, writer_components) writer_updates[writer_tab] = gr.update( label=get_text("writer_tab_title", lang) ) all_updates = { **welcome_updates, **chat_updates, **code_updates, **writer_updates, } return tuple(all_updates.get(comp) for comp in all_i18n_outputs) current_lang_state.change( fn=on_language_change, inputs=[current_lang_state], outputs=all_i18n_outputs, show_progress="hidden", ) # --- App Load Handler --- conversation_store = chat_components["conversation_store"] current_conversation_id = chat_components["current_conversation_id"] history_df = chat_components["history_df"] chatbot = chat_components["chatbot"] demo.load( on_app_load, inputs=[conversation_store, current_conversation_id, current_lang_state], outputs=[ current_conversation_id, conversation_store, history_df, chatbot, current_lang_state, ], js="() => {window.dispatchEvent(new CustomEvent('appStart')); console.log('appStart'); return {};}", ) demo.queue(default_concurrency_limit=32, max_size=128) # Launch the Gradio application demo.launch( theme=gr.themes.Default(), ssr_mode=False, max_threads=64, css=CSS, head="", head_paths=["./static/toastify.html", "./static/app.html"], )