Spaces:
Running
Running
GitHub Action
commited on
Commit
·
6e4938d
1
Parent(s):
5442d39
Sync ling-space changes from GitHub commit b68e479
Browse files- app.py +9 -0
- static/app.html +29 -44
- tab_code.py +42 -7
app.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
import uuid
|
|
|
|
| 3 |
from datetime import datetime
|
| 4 |
from gradio.analytics import ANALYTICS_URL
|
| 5 |
import pandas as pd
|
|
@@ -9,6 +10,13 @@ from tab_code import create_code_tab
|
|
| 9 |
from tab_smart_writer import create_smart_writer_tab
|
| 10 |
from tab_test import run_model_handler_test, run_clear_chat_test
|
| 11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
def get_history_df(history):
|
| 13 |
if not history:
|
| 14 |
return pd.DataFrame({'ID': [], '对话': []})
|
|
@@ -63,6 +71,7 @@ footer {
|
|
| 63 |
|
| 64 |
if __name__ == "__main__":
|
| 65 |
# Instantiate the model handler with the configuration
|
|
|
|
| 66 |
model_handler = ModelHandler()
|
| 67 |
|
| 68 |
with gr.Blocks(analytics_enabled=False,
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import uuid
|
| 3 |
+
import logging
|
| 4 |
from datetime import datetime
|
| 5 |
from gradio.analytics import ANALYTICS_URL
|
| 6 |
import pandas as pd
|
|
|
|
| 10 |
from tab_smart_writer import create_smart_writer_tab
|
| 11 |
from tab_test import run_model_handler_test, run_clear_chat_test
|
| 12 |
|
| 13 |
+
# Configure logging
|
| 14 |
+
logging.basicConfig(
|
| 15 |
+
level=logging.INFO,
|
| 16 |
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
| 17 |
+
)
|
| 18 |
+
logger = logging.getLogger(__name__)
|
| 19 |
+
|
| 20 |
def get_history_df(history):
|
| 21 |
if not history:
|
| 22 |
return pd.DataFrame({'ID': [], '对话': []})
|
|
|
|
| 71 |
|
| 72 |
if __name__ == "__main__":
|
| 73 |
# Instantiate the model handler with the configuration
|
| 74 |
+
logger.info("Starting Ling Space Application...")
|
| 75 |
model_handler = ModelHandler()
|
| 76 |
|
| 77 |
with gr.Blocks(analytics_enabled=False,
|
static/app.html
CHANGED
|
@@ -61,6 +61,31 @@
|
|
| 61 |
// Placeholder for future functionality
|
| 62 |
SpaceApp.toastInfo("WebGeneratorTab toggled.");
|
| 63 |
SpaceApp.unloadLastTab();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
}
|
| 65 |
};
|
| 66 |
})(),
|
|
@@ -70,50 +95,6 @@
|
|
| 70 |
init: function () {
|
| 71 |
console.info("WritingAssistantTab initialized.");
|
| 72 |
},
|
| 73 |
-
toggle: function () {
|
| 74 |
-
// Placeholder for future functionality
|
| 75 |
-
SpaceApp.toastInfo("WritingAssistantTab toggled.");
|
| 76 |
-
SpaceApp.unloadLastTab();
|
| 77 |
-
|
| 78 |
-
// 找到 id = 'writing-editor' 的元素,设置操作快捷键。
|
| 79 |
-
// Tab - 'btn-action-accept-flow' 按钮点击
|
| 80 |
-
// Shift + Tab - 'btn-action-change-flow' 按钮点击
|
| 81 |
-
// Cmd/Ctrl + Enter - 'btn-action-create-paragraph' 按钮点击
|
| 82 |
-
// Shift + Enter - 'btn-action-change-paragraph' 按钮点击
|
| 83 |
-
const editor = document.getElementById('writing-editor');
|
| 84 |
-
if (editor) {
|
| 85 |
-
// 如果已经设置过监听器,就不重复设置
|
| 86 |
-
if (editor.getAttribute('data-listener-set') === 'true') {
|
| 87 |
-
console.info("Writing Assistant Editor already has listeners set.");
|
| 88 |
-
return;
|
| 89 |
-
}
|
| 90 |
-
|
| 91 |
-
const idToEventFilterList = [
|
| 92 |
-
['btn-action-change-flow', (e) => e.shiftKey && e.key === 'Tab'],
|
| 93 |
-
['btn-action-accept-flow', (e) => !e.shiftKey && e.key === 'Tab'],
|
| 94 |
-
['btn-action-change-paragraph', (e) => e.shiftKey && e.key === 'Enter'],
|
| 95 |
-
['btn-action-create-paragraph', (e) => (e.metaKey || e.ctrlKey) && e.key === 'Enter'],
|
| 96 |
-
]
|
| 97 |
-
editor.addEventListener('keydown', (e) => {
|
| 98 |
-
for (const [buttonId, filterFn] of idToEventFilterList) {
|
| 99 |
-
if (filterFn(e)) {
|
| 100 |
-
e.preventDefault();
|
| 101 |
-
const button = document.getElementById(buttonId);
|
| 102 |
-
if (button) {
|
| 103 |
-
SpaceApp.toastInfo(`Writing Assistant: Triggered action for ${buttonId}`);
|
| 104 |
-
button.click();
|
| 105 |
-
} else {
|
| 106 |
-
SpaceApp.toastError(`Writing Assistant: Button with id ${buttonId} not found.`);
|
| 107 |
-
}
|
| 108 |
-
break; // Only trigger one action per keydown
|
| 109 |
-
}
|
| 110 |
-
}
|
| 111 |
-
});
|
| 112 |
-
|
| 113 |
-
// 对已经设置过监听器的 editor,不要重复设置
|
| 114 |
-
editor.setAttribute('data-listener-set', 'true');
|
| 115 |
-
}
|
| 116 |
-
}
|
| 117 |
};
|
| 118 |
})(),
|
| 119 |
|
|
@@ -122,12 +103,16 @@
|
|
| 122 |
'tabSelect.chat': () => SpaceApp.TextGeneratorTab.toggle(),
|
| 123 |
'tabSelect.code': () => SpaceApp.WebGeneratorTab.toggle(),
|
| 124 |
'tabSelect.writing': () => SpaceApp.WritingAssistantTab.toggle(),
|
|
|
|
|
|
|
| 125 |
};
|
| 126 |
for (const [event, handler] of Object.entries(listeners)) {
|
| 127 |
window.addEventListener(event, handler);
|
| 128 |
console.info(`Registered event listener for ${event}`);
|
| 129 |
}
|
| 130 |
|
|
|
|
|
|
|
| 131 |
// type_filter, handler
|
| 132 |
// Listen for messages {type: string, payload: object}
|
| 133 |
const messages = {
|
|
|
|
| 61 |
// Placeholder for future functionality
|
| 62 |
SpaceApp.toastInfo("WebGeneratorTab toggled.");
|
| 63 |
SpaceApp.unloadLastTab();
|
| 64 |
+
},
|
| 65 |
+
toggleFullscreen: function (event) {
|
| 66 |
+
const isFullscreen = event.detail?.isFullscreen;
|
| 67 |
+
console.info(`Handling Fullscreen Toggle. Target State: ${isFullscreen}`);
|
| 68 |
+
|
| 69 |
+
const left = document.getElementById('left-panel');
|
| 70 |
+
const right = document.getElementById('right-panel');
|
| 71 |
+
|
| 72 |
+
// If isFullscreen is true, we want to HIDE panels (enter fullscreen)
|
| 73 |
+
// If isFullscreen is false, we want to SHOW panels (exit fullscreen)
|
| 74 |
+
const shouldHide = isFullscreen;
|
| 75 |
+
const displayStyle = shouldHide ? 'none' : 'flex';
|
| 76 |
+
|
| 77 |
+
if (left) {
|
| 78 |
+
left.style.display = displayStyle;
|
| 79 |
+
// Also toggle class for good measure/CSS priority
|
| 80 |
+
left.classList.toggle('hidden-panel', shouldHide);
|
| 81 |
+
}
|
| 82 |
+
if (right) {
|
| 83 |
+
right.style.display = displayStyle;
|
| 84 |
+
right.classList.toggle('hidden-panel', shouldHide);
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
// Trigger resize to help charts/iframes adjust
|
| 88 |
+
setTimeout(() => window.dispatchEvent(new Event('resize')), 100);
|
| 89 |
}
|
| 90 |
};
|
| 91 |
})(),
|
|
|
|
| 95 |
init: function () {
|
| 96 |
console.info("WritingAssistantTab initialized.");
|
| 97 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
};
|
| 99 |
})(),
|
| 100 |
|
|
|
|
| 103 |
'tabSelect.chat': () => SpaceApp.TextGeneratorTab.toggle(),
|
| 104 |
'tabSelect.code': () => SpaceApp.WebGeneratorTab.toggle(),
|
| 105 |
'tabSelect.writing': () => SpaceApp.WritingAssistantTab.toggle(),
|
| 106 |
+
// New listener for fullscreen toggle
|
| 107 |
+
'tab.code.toggleFullscreen': (e) => SpaceApp.WebGeneratorTab.toggleFullscreen(e),
|
| 108 |
};
|
| 109 |
for (const [event, handler] of Object.entries(listeners)) {
|
| 110 |
window.addEventListener(event, handler);
|
| 111 |
console.info(`Registered event listener for ${event}`);
|
| 112 |
}
|
| 113 |
|
| 114 |
+
|
| 115 |
+
|
| 116 |
// type_filter, handler
|
| 117 |
// Listen for messages {type: string, payload: object}
|
| 118 |
const messages = {
|
tab_code.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
| 1 |
-
from tkinter import Label
|
| 2 |
import gradio as gr
|
| 3 |
import logging
|
| 4 |
from config import CHAT_MODEL_SPECS, LING_1T, CODE_FRAMEWORK_SPECS, STATIC_PAGE
|
|
@@ -41,10 +40,18 @@ def refresh_preview(code_type_display_name, current_code, chatbot_history):
|
|
| 41 |
return gr.HTML(final_preview_html), chatbot_history
|
| 42 |
|
| 43 |
def toggle_fullscreen(is_fullscreen):
|
|
|
|
|
|
|
|
|
|
| 44 |
is_fullscreen = not is_fullscreen
|
| 45 |
new_button_text = "退出全屏" if is_fullscreen else "全屏预览"
|
| 46 |
-
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
def log_js_error(error_text, chatbot_history):
|
| 50 |
"""Appends a JavaScript error received from the frontend to the log chatbot."""
|
|
@@ -71,9 +78,36 @@ def create_code_tab():
|
|
| 71 |
""")
|
| 72 |
fullscreen_state = gr.State(False)
|
| 73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
with gr.Row(elem_id="indicator-code-tab"):
|
| 75 |
-
with gr.Column(scale=1) as left_panel:
|
| 76 |
-
with gr.Column(scale=1): # Settings Panel
|
| 77 |
code_framework_dropdown = create_code_framework_selector(
|
| 78 |
framework_specs=CODE_FRAMEWORK_SPECS,
|
| 79 |
default_framework_constant=STATIC_PAGE
|
|
@@ -121,7 +155,7 @@ def create_code_tab():
|
|
| 121 |
code_output = gr.Code(language="html", label="生成的代码", interactive=True)
|
| 122 |
refresh_button = gr.Button("刷新预览")
|
| 123 |
|
| 124 |
-
with gr.Column(scale=1):
|
| 125 |
log_chatbot = gr.Chatbot(label="生成日志", height=300)
|
| 126 |
|
| 127 |
js_error_channel = gr.Textbox(visible=True, elem_classes=["js_error_channel"], label="Debug Error Channel", interactive=False)
|
|
@@ -172,7 +206,8 @@ def create_code_tab():
|
|
| 172 |
fullscreen_button.click(
|
| 173 |
fn=toggle_fullscreen,
|
| 174 |
inputs=[fullscreen_state],
|
| 175 |
-
outputs=[fullscreen_state, fullscreen_button,
|
|
|
|
| 176 |
)
|
| 177 |
|
| 178 |
js_error_channel.change(
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
import logging
|
| 3 |
from config import CHAT_MODEL_SPECS, LING_1T, CODE_FRAMEWORK_SPECS, STATIC_PAGE
|
|
|
|
| 40 |
return gr.HTML(final_preview_html), chatbot_history
|
| 41 |
|
| 42 |
def toggle_fullscreen(is_fullscreen):
|
| 43 |
+
logger.info(f"--- [Toggle Fullscreen] Called ---")
|
| 44 |
+
logger.info(f"Current state before toggle: {is_fullscreen}")
|
| 45 |
+
|
| 46 |
is_fullscreen = not is_fullscreen
|
| 47 |
new_button_text = "退出全屏" if is_fullscreen else "全屏预览"
|
| 48 |
+
|
| 49 |
+
logger.info(f"New state: {is_fullscreen}")
|
| 50 |
+
|
| 51 |
+
return (
|
| 52 |
+
is_fullscreen,
|
| 53 |
+
gr.update(value=new_button_text)
|
| 54 |
+
)
|
| 55 |
|
| 56 |
def log_js_error(error_text, chatbot_history):
|
| 57 |
"""Appends a JavaScript error received from the frontend to the log chatbot."""
|
|
|
|
| 78 |
""")
|
| 79 |
fullscreen_state = gr.State(False)
|
| 80 |
|
| 81 |
+
# JavaScript to dispatch a custom event for fullscreen toggle
|
| 82 |
+
# Instead of relying on the potentially stale 'is_fullscreen' state passed from Python,
|
| 83 |
+
# we check the actual DOM state of the panel to decide what to do.
|
| 84 |
+
dispatch_fullscreen_event_js = """
|
| 85 |
+
() => {
|
| 86 |
+
const left = document.getElementById('left-panel');
|
| 87 |
+
let isCurrentlyVisible = true;
|
| 88 |
+
|
| 89 |
+
if (left) {
|
| 90 |
+
// Check if hidden class is present or display is none
|
| 91 |
+
// Note: We verify both class and inline style to be safe
|
| 92 |
+
const isHidden = left.classList.contains('hidden-panel') || window.getComputedStyle(left).display === 'none';
|
| 93 |
+
isCurrentlyVisible = !isHidden;
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
// Logic:
|
| 97 |
+
// If panels are currently VISIBLE -> We want to enter Fullscreen (True)
|
| 98 |
+
// If panels are currently HIDDEN -> We want to exit Fullscreen (False)
|
| 99 |
+
const targetState = isCurrentlyVisible;
|
| 100 |
+
|
| 101 |
+
console.log("DOM Check - Panel Visible:", isCurrentlyVisible, "-> Target Fullscreen:", targetState);
|
| 102 |
+
window.dispatchEvent(new CustomEvent('tab.code.toggleFullscreen', { detail: { isFullscreen: targetState } }));
|
| 103 |
+
|
| 104 |
+
return targetState;
|
| 105 |
+
}
|
| 106 |
+
"""
|
| 107 |
+
|
| 108 |
with gr.Row(elem_id="indicator-code-tab"):
|
| 109 |
+
with gr.Column(scale=1, visible=True, elem_id="left-panel") as left_panel:
|
| 110 |
+
with gr.Column(scale=1): # Settings Panel
|
| 111 |
code_framework_dropdown = create_code_framework_selector(
|
| 112 |
framework_specs=CODE_FRAMEWORK_SPECS,
|
| 113 |
default_framework_constant=STATIC_PAGE
|
|
|
|
| 155 |
code_output = gr.Code(language="html", label="生成的代码", interactive=True)
|
| 156 |
refresh_button = gr.Button("刷新预览")
|
| 157 |
|
| 158 |
+
with gr.Column(scale=1, elem_id="right-panel") as right_panel:
|
| 159 |
log_chatbot = gr.Chatbot(label="生成日志", height=300)
|
| 160 |
|
| 161 |
js_error_channel = gr.Textbox(visible=True, elem_classes=["js_error_channel"], label="Debug Error Channel", interactive=False)
|
|
|
|
| 206 |
fullscreen_button.click(
|
| 207 |
fn=toggle_fullscreen,
|
| 208 |
inputs=[fullscreen_state],
|
| 209 |
+
outputs=[fullscreen_state, fullscreen_button],
|
| 210 |
+
js=dispatch_fullscreen_event_js
|
| 211 |
)
|
| 212 |
|
| 213 |
js_error_channel.change(
|