gaeunseo commited on
Commit
414ee54
ยท
verified ยท
1 Parent(s): a835322

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -30
app.py CHANGED
@@ -1,33 +1,85 @@
1
  import time
2
  import gradio as gr
 
 
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
- ์˜ค๋ฅธ์ชฝ์— ๐Ÿง‘ ์ด๋ชจํ‹ฐ์ฝ˜์ด ์žˆ๋Š” wrapper ์•ˆ์— ๋งํ’์„ ์„ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค.
12
- Start Typing์„ ๋ˆ„๋ฅด๋ฉด ์ด์ „ ์ƒํƒœ๊ฐ€ ๋ฆฌ์…‹๋ฉ๋‹ˆ๋‹ค.
13
  """
14
  bubble_content = ""
15
- # wrapper ์‹œ์ž‘: ์ „์ฒด ๋„ˆ๋น„๋ฅผ ์ฑ„์šฐ๊ณ , ์˜ค๋ฅธ์ชฝ ์ •๋ ฌํ•˜๋Š” flex ์ปจํ…Œ์ด๋„ˆ
16
  wrapper_start = (
17
  """<div class="human-wrapper" style="display: flex; align-items: flex-end; justify-content: flex-end; gap: 5px; width: 100%;">"""
18
  )
19
- # ๋งํ’์„  ์ปจํ…Œ์ด๋„ˆ ์‹œ์ž‘
20
  bubble_start = """<div id="human_message" class="speech-bubble human">"""
21
  bubble_end = "</div>"
22
- # ์˜ค๋ฅธ์ชฝ์— ๊ณ ์ •๋  ์ด๋ชจํ‹ฐ์ฝ˜
23
  emoji_html = "<div class='emoji'>๐Ÿง‘</div>"
24
  wrapper_end = "</div>"
25
-
26
- # ์ดˆ๊ธฐ ๋นˆ ๋งํ’์„ ๊ณผ ์ด๋ชจํ‹ฐ์ฝ˜ ์ถœ๋ ฅ
27
- html = wrapper_start + bubble_start + bubble_end + emoji_html + wrapper_end
28
- yield html
29
 
30
- # ํ•œ ๊ธ€์ž์”ฉ ์ถ”๊ฐ€ํ•˜์—ฌ streaming ์—…๋ฐ์ดํŠธ
 
 
 
31
  for i, ch in enumerate(human_message):
32
  bubble_content += f"<span data-index='{i}'>{ch}</span>"
33
  current_html = wrapper_start + bubble_start + bubble_content + bubble_end + emoji_html + wrapper_end
@@ -35,23 +87,24 @@ def stream_human_message():
35
  time.sleep(0.05)
36
 
37
  with gr.Blocks() as demo:
38
- # ์ „์—ญ์ ์œผ๋กœ ํ•œ ๋ฒˆ๋งŒ ๋กœ๋“œ๋˜๋Š” ์Šคํฌ๋ฆฝํŠธ: ์ด๋ฒคํŠธ ์œ„์ž„์œผ๋กœ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€๋˜๋Š” span์˜ ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
 
 
39
  gr.HTML(
40
  """
41
  <script>
42
- // human ๋งํ’์„  ๋‚ด๋ถ€์˜ span[data-index]์— ๋Œ€ํ•ด ํด๋ฆญ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
43
  document.addEventListener("click", function(event) {
 
44
  if (event.target && event.target.matches("div.speech-bubble.human span[data-index]")) {
45
  var span = event.target;
46
- // ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด human ๋งํ’์„  ์ปจํ…Œ์ด๋„ˆ ์„ ํƒ
47
  var container = span.closest("div.speech-bubble.human");
48
  // ๊ธฐ์กด์— ์‚ฝ์ž…๋œ โœ‚๏ธ ์ด๋ชจํ‹ฐ์ฝ˜(ํด๋ž˜์Šค "scissor") ์ œ๊ฑฐ
49
  var oldScissors = container.querySelectorAll("span.scissor");
50
  oldScissors.forEach(function(s) { s.remove(); });
51
- // ๋ชจ๋“  span์˜ ์ƒ‰์ƒ์„ ์›๋ž˜ ์ƒ‰์œผ๋กœ ์ดˆ๊ธฐํ™”
52
  var spans = container.querySelectorAll("span[data-index]");
53
  spans.forEach(function(s) { s.style.color = ''; });
54
- // ํด๋ฆญํ•œ span ๋ฐ”๋กœ ๋’ค์— โœ‚๏ธ ์ด๋ชจํ‹ฐ์ฝ˜ ์‚ฝ์ž…
55
  var scissor = document.createElement('span');
56
  scissor.textContent = 'โœ‚๏ธ';
57
  scissor.classList.add("scissor");
@@ -70,18 +123,18 @@ with gr.Blocks() as demo:
70
  """
71
  )
72
 
73
- # CSS ์Šคํƒ€์ผ ์ ์šฉ
74
  gr.HTML(
75
  """
76
  <style>
77
- /* ์ „์ฒด ์ฑ„ํŒ… ์˜์—ญ: ์„ธ๋กœ ๋ฐฐ์น˜ ๋ฐ ๊ฐ„๊ฒฉ ํ™•๋ณด */
78
  .chat-container {
79
  display: flex;
80
  flex-direction: column;
81
  gap: 10px;
82
  width: 100%;
83
  }
84
- /* ๋งํ’์„  ๊ธฐ๋ณธ ์Šคํƒ€์ผ */
85
  .speech-bubble {
86
  position: relative;
87
  padding: 10px 15px;
@@ -91,12 +144,11 @@ with gr.Blocks() as demo:
91
  font-size: 16px;
92
  line-height: 1.4;
93
  }
94
- /* Human ๋งํ’์„ : ๋ฐฐ๊ฒฝ์ƒ‰ ๋ฐ ์˜ค๋ฅธ์ชฝ์— ๋ฐฐ์น˜ (wrapper์—์„œ ์ •๋ ฌ) */
95
  .human {
96
  background: #d0f0d0;
97
  margin-right: 10px;
98
  }
99
- /* Human ๋งํ’์„ ์˜ ๊ผฌ๋ฆฌ (์˜ค๋ฅธ์ชฝ) */
100
  .human::after {
101
  content: "";
102
  position: absolute;
@@ -106,12 +158,11 @@ with gr.Blocks() as demo:
106
  border-style: solid;
107
  border-color: transparent transparent transparent #d0f0d0;
108
  }
109
- /* AI ๋งํ’์„ : ๋ฐฐ๊ฒฝ์ƒ‰ ๋ฐ ์™ผ์ชฝ์— ๋ฐฐ์น˜ (wrapper์—์„œ ์ •๋ ฌ) */
110
  .ai {
111
  background: #e0e0e0;
112
  margin-left: 10px;
113
  }
114
- /* AI ๋งํ’์„ ์˜ ๊ผฌ๋ฆฌ (์™ผ์ชฝ) */
115
  .ai::after {
116
  content: "";
117
  position: absolute;
@@ -121,7 +172,7 @@ with gr.Blocks() as demo:
121
  border-style: solid;
122
  border-color: transparent #e0e0e0 transparent transparent;
123
  }
124
- /* Emoji ์•„์ด์ฝ˜ ์Šคํƒ€์ผ */
125
  .emoji {
126
  font-size: 24px;
127
  line-height: 1;
@@ -133,9 +184,10 @@ with gr.Blocks() as demo:
133
  gr.Markdown("## Chat Interface")
134
 
135
  with gr.Column(elem_classes="chat-container"):
136
- # Human ๋ฉ”์‹œ์ง€ (์œ„์ชฝ, streaming)
137
- human_bubble = gr.HTML("")
138
- # AI ๋ฉ”์‹œ์ง€ (์•„๋ž˜์ชฝ, ๊ณ ์ •) - ์™ผ์ชฝ์— ๐Ÿค– ์ด๋ชจํ‹ฐ์ฝ˜์„ ์ถ”๊ฐ€ํ•˜๋Š” wrapper ์‚ฌ์šฉ
 
139
  ai_html = """
140
  <div class="ai-wrapper" style="display: flex; align-items: flex-end; justify-content: flex-start; gap: 5px; width: 100%;">
141
  <div class="emoji">๐Ÿค–</div>
@@ -144,7 +196,9 @@ with gr.Blocks() as demo:
144
  """
145
  ai_bubble = gr.HTML(ai_html)
146
 
 
147
  start_button = gr.Button("Start Typing")
148
  start_button.click(fn=stream_human_message, outputs=human_bubble)
149
 
150
  demo.launch()
 
 
1
  import time
2
  import gradio as gr
3
+ import random
4
+ from datasets import load_dataset
5
 
6
+ def get_random_row_from_dataset():
7
+ """
8
+ Hugging Face Dataset repository 'gaeunseo/Taskmaster_sample_data'์˜ train split์—์„œ
9
+ conversation_id๋ณ„๋กœ ๊ทธ๋ฃนํ™”ํ•œ ํ›„, ๊ฐ™์€ conversation_id๋ฅผ ๊ฐ€์ง„ ๋ชจ๋“  ํ–‰๋“ค์˜ used ์ปฌ๋Ÿผ์ด False์ด๊ณ ,
10
+ ๊ทธ ๊ทธ๋ฃน ๋‚ด์— overlapping ์ปฌ๋Ÿผ์ด "TT"์ธ ํ–‰์ด ์กด์žฌํ•˜๋Š” ๊ทธ๋ฃน๋“ค ์ค‘์—์„œ ๋žœ๋คํ•˜๊ฒŒ ํ•˜๋‚˜์˜ ๊ทธ๋ฃน์„ ์„ ํƒํ•˜๊ณ ,
11
+ ํ•ด๋‹น ๊ทธ๋ฃน ๋‚ด์—์„œ overlapping ์ปฌ๋Ÿผ์ด "TT"์ธ ํ–‰์„ ์„ ํƒํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
12
+ """
13
+ # ๋ฐ์ดํ„ฐ์…‹ ๋กœ๋“œ (split ์ด๋ฆ„์€ ์ƒํ™ฉ์— ๋งž๊ฒŒ ์กฐ์ •)
14
+ ds = load_dataset("gaeunseo/Taskmaster_sample_data", split="train")
15
+
16
+ # conversation_id๋ณ„๋กœ ํ–‰๋“ค์„ ๊ทธ๋ฃนํ™”
17
+ conversation_groups = {}
18
+ for row in ds:
19
+ cid = row["conversation_id"]
20
+ conversation_groups.setdefault(cid, []).append(row)
21
+
22
+ # ๋ชจ๋“  ํ–‰๋“ค์˜ used ์ปฌ๋Ÿผ์ด False์ด๊ณ , ๊ทธ๋ฃน ๋‚ด์— overlapping ์ปฌ๋Ÿผ์ด "TT"์ธ ํ–‰์ด ์กด์žฌํ•˜๋Š” ๊ทธ๋ฃน๋งŒ ํ•„ํ„ฐ๋ง
23
+ valid_groups = [
24
+ group for group in conversation_groups.values()
25
+ if all(not row["used"] for row in group) and any(row["overlapping"] == "TT" for row in group)
26
+ ]
27
+
28
+ if not valid_groups:
29
+ return None # ์œ ํšจํ•œ ๋Œ€ํ™” ๊ทธ๋ฃน์ด ์—†์œผ๋ฉด None ๋ฐ˜ํ™˜
30
+
31
+ # ์œ ํšจํ•œ ๊ทธ๋ฃน ์ค‘ ๋žœ๋คํ•˜๊ฒŒ ํ•˜๋‚˜ ์„ ํƒ
32
+ chosen_group = random.choice(valid_groups)
33
+ # ์„ ํƒ๋œ ๊ทธ๋ฃน ๋‚ด์—์„œ overlapping ์ปฌ๋Ÿผ์ด "TT"์ธ ํ–‰์„ ์„ ํƒ (์—ฌ๋Ÿฌ ๊ฐœ๋ผ๋ฉด ์ฒซ ๋ฒˆ์งธ ๊ฒƒ์„ ์‚ฌ์šฉ)
34
+ for row in chosen_group:
35
+ if row["overlapping"] == "TT":
36
+ return text
37
+
38
+ # ๋ฐ์ดํ„ฐ์…‹์—์„œ ํ•˜๋‚˜์˜ ํ–‰์„ ๊ฐ€์ ธ์™€์„œ human_message์™€ ai_message์— ํ• ๋‹น
39
+ row = get_random_row_from_dataset()
40
+ if row is None:
41
+ human_message = "No valid conversation available."
42
+ ai_message = "No valid conversation available."
43
+ else:
44
+ raw_text = row['text']
45
+ human_message = raw_text.split("[turn]")[0].strip()
46
+ ai_message = raw_text.split("[turn]")[1].strip()
47
+
48
+ #############################################
49
+ # ์ดํ›„ ์•„๋ž˜๋Š” ๊ธฐ์กด ์ฑ„ํŒ… ์ธํ„ฐํŽ˜์ด์Šค ์ฝ”๋“œ (๋งํ’์„ , ์ด๋ชจํ‹ฐ์ฝ˜, ํƒ€์ดํ•‘ ํšจ๊ณผ, ํด๋ฆญ ์ธํ„ฐ๋ž™์…˜) ์ž…๋‹ˆ๋‹ค.
50
+ #############################################
51
+
52
+ def get_initial_human_html():
53
+ """
54
+ ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ Human ๋งํ’์„ (๋นˆ ๋‚ด์šฉ)๊ณผ ์˜ค๋ฅธ์ชฝ์— ๐Ÿง‘ ์ด๋ชจํ‹ฐ์ฝ˜์ด ๋ณด์ด๋„๋ก ์ดˆ๊ธฐ HTML ๋ฐ˜ํ™˜
55
+ """
56
+ wrapper_start = (
57
+ """<div class="human-wrapper" style="display: flex; align-items: flex-end; justify-content: flex-end; gap: 5px; width: 100%;">"""
58
+ )
59
+ bubble_start = """<div id="human_message" class="speech-bubble human">"""
60
+ bubble_end = "</div>"
61
+ emoji_html = "<div class='emoji'>๐Ÿง‘</div>"
62
+ wrapper_end = "</div>"
63
+ return wrapper_start + bubble_start + bubble_end + emoji_html + wrapper_end
64
 
65
  def stream_human_message():
66
  """
67
+ Start Typing ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ human_message๋ฅผ ํ•œ ๊ธ€์ž์”ฉ ํƒ€์ดํ•‘ ํšจ๊ณผ๋กœ ์ถœ๋ ฅ.
68
+ ์ด์ „ ์ƒํƒœ(โœ‚๏ธ ์•„์ด์ฝ˜, ํšŒ์ƒ‰ ์ฒ˜๋ฆฌ ๋“ฑ)๋Š” ๋ฆฌ์…‹๋ฉ๋‹ˆ๋‹ค.
 
69
  """
70
  bubble_content = ""
 
71
  wrapper_start = (
72
  """<div class="human-wrapper" style="display: flex; align-items: flex-end; justify-content: flex-end; gap: 5px; width: 100%;">"""
73
  )
 
74
  bubble_start = """<div id="human_message" class="speech-bubble human">"""
75
  bubble_end = "</div>"
 
76
  emoji_html = "<div class='emoji'>๐Ÿง‘</div>"
77
  wrapper_end = "</div>"
 
 
 
 
78
 
79
+ # ์ดˆ๊ธฐ ์ƒํƒœ (๋นˆ ๋งํ’์„ ๊ณผ ์ด๋ชจํ‹ฐ์ฝ˜)
80
+ yield wrapper_start + bubble_start + bubble_end + emoji_html + wrapper_end
81
+
82
+ # human_message๋ฅผ ํ•œ ๊ธ€์ž์”ฉ ์ถ”๊ฐ€ (ํƒ€์ดํ•‘ ํšจ๊ณผ)
83
  for i, ch in enumerate(human_message):
84
  bubble_content += f"<span data-index='{i}'>{ch}</span>"
85
  current_html = wrapper_start + bubble_start + bubble_content + bubble_end + emoji_html + wrapper_end
 
87
  time.sleep(0.05)
88
 
89
  with gr.Blocks() as demo:
90
+ # ํŽ˜์ด์ง€ ์ƒ๋‹จ์— ๋‹จ ํ•œ ๋ฒˆ ๋กœ๋“œ๋  ์Šคํฌ๋ฆฝํŠธ:
91
+ # - Human ๋งํ’์„  ๋‚ด์˜ ๏ฟฝ๏ฟฝ๏ฟฝ <span data-index="...">๋ฅผ ํด๋ฆญํ•˜๋ฉด โœ‚๏ธ ์ด๋ชจํ‹ฐ์ฝ˜์ด ํ•ด๋‹น ์œ„์น˜์— ์‚ฝ์ž…๋˜๊ณ ,
92
+ # ๊ทธ ์ดํ›„์˜ ํ…์ŠคํŠธ ์ƒ‰์ƒ์ด ํšŒ์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ๋˜๋„๋ก ์ด๋ฒคํŠธ ์œ„์ž„ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
93
  gr.HTML(
94
  """
95
  <script>
 
96
  document.addEventListener("click", function(event) {
97
+ // Human ๋งํ’์„  ๋‚ด์˜ <span data-index="...">๊ฐ€ ํด๋ฆญ๋˜์—ˆ์„ ๋•Œ๋งŒ ์ฒ˜๋ฆฌ
98
  if (event.target && event.target.matches("div.speech-bubble.human span[data-index]")) {
99
  var span = event.target;
 
100
  var container = span.closest("div.speech-bubble.human");
101
  // ๊ธฐ์กด์— ์‚ฝ์ž…๋œ โœ‚๏ธ ์ด๋ชจํ‹ฐ์ฝ˜(ํด๋ž˜์Šค "scissor") ์ œ๊ฑฐ
102
  var oldScissors = container.querySelectorAll("span.scissor");
103
  oldScissors.forEach(function(s) { s.remove(); });
104
+ // ๋ชจ๋“  span์˜ ์ƒ‰์ƒ์„ ์ดˆ๊ธฐํ™”
105
  var spans = container.querySelectorAll("span[data-index]");
106
  spans.forEach(function(s) { s.style.color = ''; });
107
+ // ํด๋ฆญํ•œ span ๋ฐ”๋กœ ๋’ค์— โœ‚๏ธ ์•„์ด์ฝ˜ ์‚ฝ์ž…
108
  var scissor = document.createElement('span');
109
  scissor.textContent = 'โœ‚๏ธ';
110
  scissor.classList.add("scissor");
 
123
  """
124
  )
125
 
126
+ # CSS ์Šคํƒ€์ผ (๋งํ’์„  ๋ชจ์–‘, ์ด๋ชจํ‹ฐ์ฝ˜, ์œ„์น˜ ๋“ฑ)
127
  gr.HTML(
128
  """
129
  <style>
130
+ /* ์ „์ฒด ์ฑ„ํŒ… ์˜์—ญ */
131
  .chat-container {
132
  display: flex;
133
  flex-direction: column;
134
  gap: 10px;
135
  width: 100%;
136
  }
137
+ /* ๊ณตํ†ต ๋งํ’์„  ์Šคํƒ€์ผ */
138
  .speech-bubble {
139
  position: relative;
140
  padding: 10px 15px;
 
144
  font-size: 16px;
145
  line-height: 1.4;
146
  }
147
+ /* Human ๋งํ’์„  (์˜ค๋ฅธ์ชฝ ์ •๋ ฌ, ์ดˆ๋ก ๋ฐฐ๊ฒฝ) */
148
  .human {
149
  background: #d0f0d0;
150
  margin-right: 10px;
151
  }
 
152
  .human::after {
153
  content: "";
154
  position: absolute;
 
158
  border-style: solid;
159
  border-color: transparent transparent transparent #d0f0d0;
160
  }
161
+ /* AI ๋งํ’์„  (์™ผ์ชฝ ์ •๋ ฌ, ํšŒ์ƒ‰ ๋ฐฐ๊ฒฝ) */
162
  .ai {
163
  background: #e0e0e0;
164
  margin-left: 10px;
165
  }
 
166
  .ai::after {
167
  content: "";
168
  position: absolute;
 
172
  border-style: solid;
173
  border-color: transparent #e0e0e0 transparent transparent;
174
  }
175
+ /* ์ด๋ชจํ‹ฐ์ฝ˜ ์Šคํƒ€์ผ */
176
  .emoji {
177
  font-size: 24px;
178
  line-height: 1;
 
184
  gr.Markdown("## Chat Interface")
185
 
186
  with gr.Column(elem_classes="chat-container"):
187
+ # ํŽ˜์ด์ง€ ๋กœ๋“œ ์‹œ Human ๋งํ’์„ (๋นˆ ๋ฉ”์‹œ์ง€)๊ณผ ์˜ค๋ฅธ์ชฝ ๐Ÿง‘ ์ด๋ชจํ‹ฐ์ฝ˜์ด ๋ณด์ด๋„๋ก ์ดˆ๊ธฐ HTML ์ ์šฉ
188
+ human_bubble = gr.HTML(get_initial_human_html())
189
+
190
+ # AI ๋งํ’์„ : ์™ผ์ชฝ์— ๐Ÿค– ์ด๋ชจํ‹ฐ์ฝ˜๊ณผ ํ•จ๊ป˜ ๊ณ ์ • ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
191
  ai_html = """
192
  <div class="ai-wrapper" style="display: flex; align-items: flex-end; justify-content: flex-start; gap: 5px; width: 100%;">
193
  <div class="emoji">๐Ÿค–</div>
 
196
  """
197
  ai_bubble = gr.HTML(ai_html)
198
 
199
+ # Start Typing ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด human_message๊ฐ€ ์ŠคํŠธ๋ฆฌ๋ฐ(ํƒ€์ดํ•‘ ํšจ๊ณผ)๋˜๋ฉฐ, ์ด์ „์— ์žˆ๋˜ โœ‚๏ธ/ํšŒ์ƒ‰ ์ฒ˜๋ฆฌ ๋“ฑ์€ ๋ฆฌ์…‹๋ฉ๋‹ˆ๋‹ค.
200
  start_button = gr.Button("Start Typing")
201
  start_button.click(fn=stream_human_message, outputs=human_bubble)
202
 
203
  demo.launch()
204
+