gaeunseo commited on
Commit
8a6c153
ยท
verified ยท
1 Parent(s): 98bcf73

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -91
app.py CHANGED
@@ -1,102 +1,76 @@
1
- import time
2
  import gradio as gr
 
3
 
4
- # ํ•œ ๊ธ€์ž์”ฉ ์ŠคํŠธ๋ฆฌ๋ฐ ์ถœ๋ ฅ (ํƒ€์ดํ•‘ ํšจ๊ณผ)
5
- def stream_text(text):
6
- out = ""
7
- for ch in text:
8
- out += ch
9
- time.sleep(0.05) # ๊ธ€์ž๋‹น ์ง€์—ฐ (0.05์ดˆ)
10
- yield out
11
 
12
- # ์›๋ณธ ๋ฌธ์žฅ์„ HTML๋กœ ์ƒ์„ฑํ•˜๋Š” ํ•จ์ˆ˜
13
- def get_clickable_html(sentence, cut_index=0):
14
- html = "<div style='font-size:24px; font-family: monospace;'>"
15
- for i, ch in enumerate(sentence):
16
- if i < cut_index:
17
- # ์ด๋ฏธ ์ž˜๋ฆฐ ๋ถ€๋ถ„: ํšŒ์ƒ‰ ํ‘œ์‹œ
18
- html += f"<span style='color:gray;'>{ch}</span>"
19
- elif i == cut_index:
20
- # ํ˜„์žฌ ์ปท ์œ„์น˜: ํŒŒ๋ž€์ƒ‰์— โœ‚๏ธ ์ด๋ชจํ‹ฐ์ฝ˜ ํ‘œ์‹œ
21
- html += f"<span style='cursor:pointer; color:blue;' onclick='handleClick({i})'>{ch}โœ‚๏ธ</span>"
22
- else:
23
- # ์•„์ง ํด๋ฆญ ๊ฐ€๋Šฅํ•œ ๋ถ€๋ถ„
24
- html += f"<span style='cursor:pointer;' onclick='handleClick({i})'>{ch}</span>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  html += "</div>"
26
- return html
27
-
28
- # HTML์— ์‚ฝ์ž…ํ•  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
29
- custom_js = """
30
- <script>
31
- function handleClick(index) {
32
- document.getElementById("click_index").value = index;
33
- document.getElementById("trigger_button").click();
34
- }
35
- </script>
36
- """
37
-
38
- # "Start" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜
39
- def start_sentence(text):
40
- current_cut = 0
41
- clickable = get_clickable_html(text, current_cut) + custom_js
42
- # ์ŠคํŠธ๋ฆฌ๋ฐ์€ ์ „์ฒด ๋ฌธ์žฅ์„ ํ•œ ๊ธ€์ž์”ฉ ์ถœ๋ ฅ
43
- return stream_text(text), text, current_cut, clickable
44
-
45
- # "Restart Streaming" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜
46
- def stream_current(original_sentence, current_cut):
47
- new_text = original_sentence[current_cut:]
48
- return stream_text(new_text)
49
-
50
- # HTML์˜ ํŠน์ • ๊ธ€์ž๋ฅผ ํด๋ฆญํ•  ๋•Œ ์‹คํ–‰๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜
51
- def update_cut(index, original_sentence, current_cut):
52
- index = int(index)
53
- new_cut = current_cut
54
- if index > current_cut:
55
- new_cut = index
56
- clickable = get_clickable_html(original_sentence, new_cut) + custom_js
57
- return original_sentence, new_cut, clickable
58
 
59
  # Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
60
  with gr.Blocks() as demo:
 
61
  with gr.Row():
62
- inp = gr.Textbox(label="Enter text", placeholder="๋ฌธ์žฅ์„ ์ž…๋ ฅํ•˜์„ธ์š”...")
63
- start_btn = gr.Button("Start")
64
- # ์ƒ๋‹จ ์ŠคํŠธ๋ฆฌ๋ฐ ํ…์ŠคํŠธ ์ถœ๋ ฅ ์˜์—ญ
65
- stream_box = gr.Textbox(label="Streaming Text", interactive=False)
66
- # ํ˜„์žฌ ์ƒํƒœ์˜ ๋ฌธ์žฅ์„ ๋‹ค์‹œ ์ŠคํŠธ๋ฆฌ๋ฐํ•˜๋Š” ๋ฒ„ํŠผ
67
- stream_btn = gr.Button("Restart Streaming")
68
- # ํ•˜๏ฟฝ๏ฟฝ ์›๋ณธ ๋ฌธ์žฅ์„ HTML๋กœ ํ‘œ์‹œ (๊ฐ ๊ธ€์ž ํด๋ฆญ ๊ฐ€๋Šฅ)
69
- clickable_display = gr.HTML(label="Clickable Text")
70
-
71
- # HTML ๋‚ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ์—ฐ๋™ํ•  ์ˆจ๊ฒจ์ง„ ์ปดํฌ๋„ŒํŠธ๋“ค
72
- click_index = gr.Textbox(visible=False, elem_id="click_index")
73
- trigger_button = gr.Button("trigger", visible=False, elem_id="trigger_button")
74
-
75
- # ์›๋ณธ ๋ฌธ์žฅ๊ณผ ํ˜„์žฌ ์ปท ์ธ๋ฑ์Šค๋ฅผ ์ƒํƒœ๋กœ ์ €์žฅ
76
- original_sentence_state = gr.State("")
77
- current_cut_state = gr.State(0)
78
-
79
- # โ‘  "Start" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ: ์ž…๋ ฅ ๋ฌธ์žฅ์„ ์ƒํƒœ์— ์ €์žฅํ•˜๊ณ  ์ŠคํŠธ๋ฆฌ๋ฐ๊ณผ ํ•˜๋‹จ HTML ์ดˆ๊ธฐํ™”
80
- start_btn.click(
81
- start_sentence,
82
- inputs=inp,
83
- outputs=[stream_box, original_sentence_state, current_cut_state, clickable_display]
84
- )
85
-
86
- # โ‘ก HTML ๋‚ด ๊ธ€์ž ํด๋ฆญ โ†’ ์ˆจ๊ฒจ์ง„ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ: update_cut ํ•จ์ˆ˜ ์‹คํ–‰
87
- trigger_button.click(
88
- update_cut,
89
- inputs=[click_index, original_sentence_state, current_cut_state],
90
- outputs=[original_sentence_state, current_cut_state, clickable_display]
91
- )
92
-
93
- # โ‘ข "Restart Streaming" ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ: ํ˜„์žฌ ์ƒํƒœ(์ž˜๋ฆฐ ํ›„์˜ ๋ฌธ์žฅ)๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐ
94
- # ์—ฌ๊ธฐ์„œ stream ์ธ์ˆ˜(stream=True)๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
95
- stream_btn.click(
96
- stream_current,
97
- inputs=[original_sentence_state, current_cut_state],
98
- outputs=stream_box
99
- )
100
 
101
  demo.launch()
102
 
 
 
1
  import gradio as gr
2
+ import time
3
 
4
+ # ๋ฉ”์‹œ์ง€ ๋‚ด์šฉ ์„ค์ •
5
+ human_message = "Hello. I'd like to find a round trip commercial airline flight from San Francisco to Denver."
6
+ ai_message = "Hello, how can I help you?"
 
 
 
 
7
 
8
+ def stream_human_message():
9
+ """
10
+ Human์˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฌธ์ž ๋‹จ์œ„๋กœ ํƒ€์ดํ•‘ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค.
11
+ ๊ฐ ๋ฌธ์ž๋Š” <span> ํƒœ๊ทธ๋กœ ๊ฐ์‹ธ์„œ onclick ์ด๋ฒคํŠธ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ฆญํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
12
+ ํด๋ฆญ ์‹œ JavaScript ํ•จ์ˆ˜ handleClick()๊ฐ€ ํ˜ธ์ถœ๋˜์–ด,
13
+ ํ•ด๋‹น ๋ฌธ์ž์˜ ๋ฐ”๋กœ ๋’ค์— โœ‚๏ธ ์ด๋ชจํ‹ฐ์ฝ˜์„ ์‚ฝ์ž…ํ•˜๊ณ  ๊ทธ ๋’ค์˜ ๋ฌธ์ž๋“ค์€ ํšŒ์ƒ‰์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
14
+ """
15
+ # ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ JavaScript ์ฝ”๋“œ.
16
+ # (ํŽ˜์ด์ง€์— ๋‹จ ํ•œ ๋ฒˆ๋งŒ ๋กœ๋“œ๋˜๋„๋ก window.cutDone ํ”Œ๋ž˜๊ทธ๋กœ ์ค‘๋ณต ์‹คํ–‰์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.)
17
+ script = """
18
+ <script>
19
+ if (window.cutDone === undefined) { window.cutDone = false; }
20
+ function handleClick(span) {
21
+ if (window.cutDone) return; // ์ด๋ฏธ ํด๋ฆญํ•œ ๊ฒฝ์šฐ ๋ฌด์‹œ
22
+ window.cutDone = true;
23
+ // ํด๋ฆญํ•œ span ๋ฐ”๋กœ ๋’ค์— โœ‚๏ธ ์ด๋ชจํ‹ฐ์ฝ˜ ์‚ฝ์ž…
24
+ var scissor = document.createElement('span');
25
+ scissor.textContent = 'โœ‚๏ธ';
26
+ span.parentNode.insertBefore(scissor, span.nextSibling);
27
+ // ํด๋ฆญํ•œ ๋ฌธ์ž์˜ data-index ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ์ดํ›„ ๋ฌธ์ž๋“ค์˜ ์ƒ‰์ƒ์„ ํšŒ์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ
28
+ var cutIndex = parseInt(span.getAttribute('data-index'));
29
+ var spans = span.parentNode.querySelectorAll('span[data-index]');
30
+ spans.forEach(function(s) {
31
+ var idx = parseInt(s.getAttribute('data-index'));
32
+ if (idx > cutIndex) {
33
+ s.style.color = 'grey';
34
+ }
35
+ });
36
+ }
37
+ </script>
38
+ """
39
+ # human ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐ์‹ธ๋Š” HTML ์ปจํ…Œ์ด๋„ˆ ์‹œ์ž‘ (์˜ค๋ฅธ์ชฝ ์ •๋ ฌ, ๋ฐฐ๊ฒฝ ๋ฐ ํ…Œ๋‘๋ฆฌ ์Šคํƒ€์ผ)
40
+ html = script + (
41
+ "<div id='human_message' "
42
+ "style='text-align: right; background-color: #d0f0d0; padding: 10px; "
43
+ "border-radius: 10px; display: inline-block;'>"
44
+ )
45
+ # ์ดˆ๊ธฐ ์ƒํƒœ: ์•„์ง ๋‚ด์šฉ์ด ์—†์„ ๋•Œ
46
+ yield html
47
+ # ๋ฌธ์ž ํ•˜๋‚˜์”ฉ <span> ํƒœ๊ทธ๋กœ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ ์ŠคํŠธ๋ฆฌ๋ฐ ํšจ๊ณผ๋ฅผ ์ค๋‹ˆ๋‹ค.
48
+ for i, ch in enumerate(human_message):
49
+ html += f"<span data-index='{i}' onclick='handleClick(this)'>{ch}</span>"
50
+ yield html
51
+ time.sleep(0.05) # ํƒ€์ดํ•‘ ํšจ๊ณผ๋ฅผ ์œ„ํ•œ ๋”œ๋ ˆ์ด (0.05์ดˆ)
52
+ # ์ปจํ…Œ์ด๋„ˆ ์ข…๋ฃŒ ํƒœ๊ทธ ์ถ”๊ฐ€
53
  html += "</div>"
54
+ yield html
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
  # Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
57
  with gr.Blocks() as demo:
58
+ gr.Markdown("## Chat Interface")
59
  with gr.Row():
60
+ # ์™ผ์ชฝ: AI ๋งํ’์„  (๊ณ ์ • ํ…์ŠคํŠธ)
61
+ with gr.Column():
62
+ ai_bubble = gr.HTML(
63
+ f"<div style='text-align: left; background-color: #e0e0e0; padding: 10px; "
64
+ "border-radius: 10px; display: inline-block;'>"
65
+ f"{ai_message}"
66
+ "</div>"
67
+ )
68
+ # ์˜ค๋ฅธ์ชฝ: Human ๋งํ’์„  (์ŠคํŠธ๋ฆฌ๋ฐ ํ…์ŠคํŠธ)
69
+ with gr.Column():
70
+ human_bubble = gr.HTML("")
71
+ # ์ŠคํŠธ๋ฆฌ๋ฐ(ํƒ€์ดํ•‘ ํšจ๊ณผ)๋ฅผ ์‹œ์ž‘ํ•  ๋ฒ„ํŠผ
72
+ start_button = gr.Button("Start Typing")
73
+ start_button.click(fn=stream_human_message, outputs=human_bubble, stream=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
  demo.launch()
76