gradio 运行 JavaScript | chatglm3-6b toggle enter 前端切换换行与提交

chatglm3-6b初始的demo网页回车键换行,shift/ctrl + 回车键没有作用,想要提交只能手动点击“submit”按钮。
在这里插入图片描述
个人觉得这样不方便,应该增加一个像通常的通讯软件可以用 shift+enter 实现提交功能。最好还能增加交换这两种按键的行为。

思路是用js实现按键监听,但是js是在gradio框架中添加的。这里有参考:
【Gradio】Building With Blocks 自定义您的演示与 CSS 和 JavaScript-CSDN博客 https://blog.csdn.net/cxyhjl/article/details/139729514

下面是实现的代码:

...
js = """
function keybinding() {
    if (typeof window.enterToSubmit === 'undefined') {
        window.enterToSubmit = true;  // Initialize the global state
    }

    function handleKeydown(event) {
        if (window.enterToSubmit) {
            if (event.key === 'Enter') {
                if (event.shiftKey) {
                    event.preventDefault();
                    const textarea = event.target;
                    const start = textarea.selectionStart;
                    const end = textarea.selectionEnd;
                    textarea.value = textarea.value.substring(0, start) + '\\n' + textarea.value.substring(end);
                    textarea.selectionStart = textarea.selectionEnd = start + 1;
                } else {
                    event.preventDefault();
                    document.getElementById('submit-button').click();
                }
            }
        } else {
            if (event.shiftKey && event.key === 'Enter') {
                event.preventDefault();
                document.getElementById('submit-button').click();
            }
        }
    }

    document.addEventListener('keydown', handleKeydown);

    // Toggle the enterToSubmit state when the toggle button is clicked
    document.getElementById('toggle-button').addEventListener('click', function() {
        window.enterToSubmit = !window.enterToSubmit;
        var toggleLabel = document.getElementById('toggle-label');
        toggleLabel.innerHTML = window.enterToSubmit 
            ? '&nbsp;'.repeat(11)+'enter : submit<br>shift+enter : newline' 
            : '&nbsp;'.repeat(11)+'enter : newline<br>shift+enter : submit';
        const inputBox = document.querySelector('textarea');
        inputBox.placeholder = "Input...\\n"+(window.enterToSubmit 
            ? ' '.repeat(11)+'enter : submit\\nshift+enter : newline' 
            : ' '.repeat(11)+'enter : newline\\nshift+enter : submit')
        +'\\nyou can toggle by clicking the "toggle enter" button in the bottom right corner';
    });
}
"""

with gr.Blocks(js=js) as demo:
    gr.HTML("""<h1 align="center">ChatGLM3-6B Gradio Simple Demo</h1>""")
    chatbot = gr.Chatbot()

    with gr.Row():
        with gr.Column(scale=4):
            with gr.Column(scale=12):
                placeholder_text="Input...\n"
                placeholder_text+=' '*11+'enter : newline\nshift+enter : submit\n'
                placeholder_text+='you can toggle by clicking the "toggle enter" button in the bottom right corner'
                user_input = gr.Textbox(show_label=False, placeholder=placeholder_text, lines=10, container=False)
            with gr.Column(min_width=32, scale=1):
                submitBtn = gr.Button("Submit",elem_id="submit-button")
        with gr.Column(scale=1):
            emptyBtn = gr.Button("Clear History")
            max_length = gr.Slider(0, 32768, value=8192, step=1.0, label="Maximum length", interactive=True)
            top_p = gr.Slider(0, 1, value=0.8, step=0.01, label="Top P", interactive=True)
            temperature = gr.Slider(0.01, 1, value=0.6, step=0.01, label="Temperature", interactive=True)
            with gr.Row():
                toggleBtn = gr.Button("toggle enter", elem_id="toggle-button")
                toggleLabel = gr.HTML("<div id='toggle-label'>"+'&nbsp;'*11+"enter : submit<br>shift+enter : newline</div>")

    def user(query, history):
        return "", history + [[parse_text(query), ""]]


    submitBtn.click(user, [user_input, chatbot], [user_input, chatbot], queue=False).then(
        predict, [chatbot, max_length, top_p, temperature], chatbot
    )
    emptyBtn.click(lambda: None, None, chatbot, queue=False)

demo.queue()
demo.launch(server_name="127.0.0.1", server_port=7870, root_path='/chatglm', inbrowser=True, share=True, show_error=True)

网页效果:
在这里插入图片描述

点击“toggle enter”按钮会切换按键行为,并且具体情况会显示在旁边的文本中,也显示在输入框空白时的placeholder文本中。

写代码过程中的几个小坑:

  • 将with gr.Blocks() as demo改为with gr.Blocks(js=js) as demo来运行js字符串中的函数。js字符串中只有一个函数定义,且并不实际调用,是可行的。其他的一些情形试了不行。

  • 按下shift+enter的默认行为不换行(gpt认为会换行,可能与设备有关),在event.shiftKey用了一些较为复杂的textarea.selectionStart之类代码。

  • toggleLabel.innerHTML 的赋值中<br>不能用’\n’,会无效。

  • inputBox.placeholder 的赋值中,空格不能用&nbsp;,就用空格字符本身,回车不能用\n<br>,要用\\n。这里太奇怪了,与上面不一致,改了好久…

为了方面调试,写了一个对多行字符串每一行问候的简单脚本,附在这里:

import gradio as gr

def greet(names_str):
    names = names_str.split('\n')
    responses = [f'Hello {name}!' for name in names]
    return '\n'.join(responses)

def user(query, history):
    response = greet(query)
    return "", history + [[query, response]]

js = """
function keybinding() {
    if (typeof window.enterToSubmit === 'undefined') {
        window.enterToSubmit = false;  // Initialize the global state
    }

    function handleKeydown(event) {
        if (window.enterToSubmit) {
            if (event.key === 'Enter') {
                if (event.shiftKey) {
                    event.preventDefault();
                    const textarea = event.target;
                    const start = textarea.selectionStart;
                    const end = textarea.selectionEnd;
                    textarea.value = textarea.value.substring(0, start) + '\\n' + textarea.value.substring(end);
                    textarea.selectionStart = textarea.selectionEnd = start + 1;
                } else {
                    event.preventDefault();
                    document.getElementById('submit-button').click();
                }
            }
        } else {
            if (event.shiftKey && event.key === 'Enter') {
                event.preventDefault();
                document.getElementById('submit-button').click();
            }
        }
    }

    document.addEventListener('keydown', handleKeydown);

    // Toggle the enterToSubmit state when the toggle button is clicked
    document.getElementById('toggle-button').addEventListener('click', function() {
        window.enterToSubmit = !window.enterToSubmit;
        var toggleLabel = document.getElementById('toggle-label');
        toggleLabel.innerHTML = window.enterToSubmit 
            ? '&nbsp;'.repeat(11)+'enter : submit<br>shift+enter : newline' 
            : '&nbsp;'.repeat(11)+'enter : newline<br>shift+enter : submit';
        const inputBox = document.querySelector('textarea');
        inputBox.placeholder = "Input...\\n"+(window.enterToSubmit 
            ? ' '.repeat(11)+'enter : submit\\nshift+enter : newline' 
            : ' '.repeat(11)+'enter : newline\\nshift+enter : submit')
        +'\\nyou can toggle by clicking the "toggle enter" button in the bottom right corner';


    });
}
"""

with gr.Blocks(js=js) as demo:
    gr.HTML("<h1 align='center'>Gradio Simple Greet</h1>")
    chatbot = gr.Chatbot()

    with gr.Row():
        with gr.Column(scale=4):
            with gr.Column(scale=12):
                placeholder_text="Input...\n"
                placeholder_text+=' '*11+'enter : newline\nshift+enter : submit\n'
                placeholder_text+='you can toggle by clicking the "toggle enter" button in the bottom right corner'
                user_input = gr.Textbox(show_label=False, placeholder=placeholder_text, lines=10, container=False)
            with gr.Column(min_width=32, scale=1):
                submitBtn = gr.Button("Submit",elem_id="submit-button")
        with gr.Column(scale=1):
            emptyBtn = gr.Button("Clear History")
            max_length = gr.Slider(0, 32768, value=8192, step=1.0, label="Maximum length", interactive=True)
            top_p = gr.Slider(0, 1, value=0.8, step=0.01, label="Top P", interactive=True)
            temperature = gr.Slider(0.01, 1, value=0.6, step=0.01, label="Temperature", interactive=True)
            with gr.Row():
                toggleBtn = gr.Button("toggle enter", elem_id="toggle-button") #behavior
                toggleLabel = gr.HTML("<div id='toggle-label'>"+'&nbsp;'*11+"enter : submit<br>shift+enter : newline</div>")

    submitBtn.click(user, [user_input, chatbot], [user_input, chatbot], queue=False)
    emptyBtn.click(lambda: None, None, chatbot, queue=False)

app, local_url, share_url = demo.launch()
__import__('webbrowser').open(local_url)
  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值