Spaces:
Running
Running
| 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"], | |
| ) | |