Jay1121 commited on
Commit
1e65567
·
verified ·
1 Parent(s): a91423b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -75
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import gradio as gr
2
  from huggingface_hub import hf_hub_download
3
  from llama_cpp import Llama
@@ -28,13 +29,14 @@ SYSTEM_PROMPT = """너는 사용자의 오랜 찐친 '똘배'야.
28
  - 반말로 편하게 대화해. 존댓말 절대 쓰지 마.
29
  - PC통신 채팅방에서 대화하듯이 텍스트 위주로 툭툭 던져.
30
  - 이모지(😊) 같은 건 쓰지 말고, 옛날 텍스트 이모티콘(^^, ㅡㅡ;, ㅋㅋ)을 주로 써.
31
- - 상대방 기분이 좋아 보이면 걱정도 해주고, 기분 좋으면 같이 좋아해줘.
32
  - 질문에는 솔직하게 대답하되, 너무 길지 않게 채팅하듯 끊어서 말해."""
33
 
34
  # ------------------------------------------------------------------
35
  # 3. 채팅 로직
36
  # ------------------------------------------------------------------
37
- def chat_response(user_input, history):
 
38
  clean_input = (user_input or "").replace(" ", "")
39
 
40
  greeting_words = ["안녕", "ㅎㅇ", "하이", "반가", "접속"]
@@ -47,7 +49,7 @@ def chat_response(user_input, history):
47
  final_instruction = (
48
  f"(사용자가 밸런스 게임을 하자고 한다. 주제는 '{topic}'이다. "
49
  "아주 고르기 곤란하고 짜증나는 두 가지 선택지(A vs B)를 제시해라. "
50
- "말투는 PC통신 아재처럼 시니컬하게 해라.) "
51
  "자, 질문해."
52
  )
53
  elif is_greeting:
@@ -56,9 +58,9 @@ def chat_response(user_input, history):
56
  final_instruction = user_input
57
 
58
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
59
- for user_msg, bot_msg in (history or []):
60
- messages.append({"role": "user", "content": user_msg})
61
- messages.append({"role": "assistant", "content": bot_msg})
62
  messages.append({"role": "user", "content": final_instruction})
63
 
64
  response = llm.create_chat_completion(
@@ -78,13 +80,13 @@ PC_COM_CSS = r"""
78
  @import url('https://cdn.jsdelivr.net/gh/neodgm/neodgm-webfont@latest/neodgm/neodgm.css');
79
 
80
  :root {
81
- --pc-bg: #000084; /* 배경: 짙은 파랑 (EGA Color) */
82
- --pc-input-bg: #000042; /* 입력창 배경: 더 어두운 파랑 */
83
- --pc-text: #FFFFFF; /* 기본 텍스트: 흰색 */
84
- --pc-user: #FFFF55; /* 유저 텍스트: 밝은 노랑 */
85
- --pc-bot: #FFFFFF; /* 봇 텍스트: 흰색 */
86
- --pc-accent: #00AAAA; /* 강조: 청록색 */
87
- --pc-grey: #AAAAAA; /* 보조: 회색 */
88
  }
89
 
90
  body, .gradio-container {
@@ -93,7 +95,6 @@ body, .gradio-container {
93
  color: var(--pc-text) !important;
94
  }
95
 
96
- /* 타이틀바 */
97
  h1 {
98
  font-family: 'NeoDunggeunmo', monospace !important;
99
  color: var(--pc-user) !important;
@@ -106,38 +107,34 @@ h1 {
106
  h1::before { content: "☎ "; }
107
  h1::after { content: " ☎"; }
108
 
109
- /* 설명 텍스트 */
110
  .gradio-container p {
111
  color: var(--pc-accent) !important;
112
  font-size: 16px !important;
113
  margin-bottom: 20px !important;
114
  }
115
 
116
- /* 1. 채팅창 크게 (가독성 UP) */
117
  .chatbot {
118
  height: 65vh !important;
119
- background-color: var(--pc-input-bg) !important; /* 배경을 어둡게 눌러줌 */
120
  border: 2px solid var(--pc-text) !important;
121
  border-radius: 0 !important;
122
  padding: 20px !important;
123
  overflow-y: scroll !important;
124
  }
125
 
126
- /* 메시지 스타일 (버블 제거, 텍스트만) */
127
  .message {
128
  background: transparent !important;
129
  border: none !important;
130
  padding: 5px 0 !important;
131
- font-size: 18px !important; /* 글씨 키움 */
132
  line-height: 1.6 !important;
133
  box-shadow: none !important;
134
  }
135
 
136
- /* 유저 메시지 */
137
  .message.user-row, .user {
138
  justify-content: flex-start !important;
139
  background: transparent !important;
140
- border-bottom: 1px dashed #333 !important; /* 구분선 */
141
  }
142
  .message.user-row .message, .user .message {
143
  color: var(--pc-user) !important;
@@ -150,7 +147,6 @@ h1::after { content: " ☎"; }
150
  margin-right: 8px;
151
  }
152
 
153
- /* 봇 메시지 */
154
  .message.bot-row, .bot {
155
  background: transparent !important;
156
  border-bottom: 1px dashed #333 !important;
@@ -165,19 +161,15 @@ h1::after { content: " ☎"; }
165
  margin-right: 8px;
166
  }
167
 
168
- /* 아바타 숨김 */
169
  .avatar { display: none !important; }
170
 
171
- /* 2. 입력창 및 버튼 레이아웃 */
172
- /* 입력창 컨테이너 */
173
  .input-container {
174
  margin-top: 10px !important;
175
  background: transparent !important;
176
  border: none !important;
177
- gap: 10px !important; /* 입력창과 전송버튼 사이 간격 */
178
  }
179
 
180
- /* 입력창 디자인 */
181
  textarea, input {
182
  background-color: var(--pc-input-bg) !important;
183
  color: var(--pc-text) !important;
@@ -189,7 +181,6 @@ textarea, input {
189
  }
190
  textarea::placeholder { color: var(--pc-grey) !important; }
191
 
192
- /* 전송 버튼 (입력창 옆) */
193
  button.primary {
194
  background: var(--pc-grey) !important;
195
  color: #000 !important;
@@ -201,7 +192,6 @@ button.primary:hover {
201
  background: var(--pc-text) !important;
202
  }
203
 
204
- /* 3. 화면 지우기 버튼 (작게) */
205
  #clear-btn {
206
  background: transparent !important;
207
  color: var(--pc-grey) !important;
@@ -210,20 +200,19 @@ button.primary:hover {
210
  padding: 2px 10px !important;
211
  margin-top: 5px !important;
212
  width: auto !important;
213
- align-self: flex-start !important;
214
  }
215
  #clear-btn:hover {
216
  color: var(--pc-text) !important;
217
  border-color: var(--pc-text) !important;
218
  }
219
 
220
- /* 4. 예시 버튼 가로 배열 */
221
  .examples {
222
  margin-top: 20px !important;
223
  border-top: 1px dashed var(--pc-grey);
224
  padding-top: 10px;
225
  }
226
- .examples .label { display: none !important; } /* Label 숨김 */
227
  .examples div.gallery {
228
  display: flex !important;
229
  flex-direction: row !important;
@@ -245,44 +234,41 @@ button.primary:hover {
245
  color: #000 !important;
246
  }
247
 
248
- /* 푸터 삭제 */
249
  footer { display: none !important; }
250
  """
251
 
252
  # ------------------------------------------------------------------
253
- # 5. App 실행 (Blocks로 레이아웃 직접 구성)
 
254
  # ------------------------------------------------------------------
255
  with gr.Blocks(theme=gr.themes.Base(), css=PC_COM_CSS, title="CHOLLIAN 98") as demo:
256
  gr.Markdown("19금 채팅방")
257
  gr.Markdown(">> 01410 접속 성공... [대화실]에 입장하셨습니다.")
258
-
259
- # ChatInterface 대신 Blocks로 수동 구성하여 레이아웃 제어
260
  chatbot = gr.Chatbot(
261
  label="대화내용",
262
  show_label=False,
263
- elem_classes="chatbot"
 
264
  )
265
-
266
- # 입력창과 전송 버튼을 나란히
267
  with gr.Row(elem_classes="input-container"):
268
  msg = gr.Textbox(
269
- scale=8,
270
- show_label=False,
271
  placeholder="할 말을 입력하세요...",
272
  container=False,
273
  autofocus=True
274
  )
275
  submit_btn = gr.Button("전 송", scale=1, variant="primary")
276
-
277
- # 화면 지우기 버튼을 작게 아래에 배치
278
  with gr.Row():
279
  clear = gr.Button("화면 지우기", elem_id="clear-btn")
280
 
281
- # 예시들을 맨 아래에 가로로
282
  gr.Examples(
283
  examples=[
284
  "하이 방가방가",
285
- "퀴즈 ㄱㄱ?",
286
  "오늘 기분 꿀꿀하네..",
287
  "야 밥 뭐먹지 추천좀",
288
  ],
@@ -290,38 +276,40 @@ with gr.Blocks(theme=gr.themes.Base(), css=PC_COM_CSS, title="CHOLLIAN 98") as d
290
  label="빠른 입력"
291
  )
292
 
293
- # 이벤트 연결
294
- def user(user_message, history):
295
- # history가 None일 경우 빈 리스트로 초기화 (에러 방지)
296
  history = history or []
297
- return "", history + [[user_message, None]]
298
-
299
- def bot(history):
300
- # history가 비어있거나 None일 경우 방어 로직
301
- if not history:
302
- return history
303
-
304
- user_message = history[-1][0]
305
- # 이전 대화 기록 포맷팅
306
- chat_history = []
307
- for u, b in history[:-1]:
308
- chat_history.append([u, b])
309
-
310
- bot_message = chat_response(user_message, chat_history)
311
- history[-1][1] = bot_message
312
- return history
313
-
314
- # 엔터키 입력 시
315
- msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
316
- bot, chatbot, chatbot
317
  )
318
- # 전송 버튼 클릭 시
319
- submit_btn.click(user, [msg, chatbot], [msg, chatbot], queue=False).then(
320
- bot, chatbot, chatbot
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  )
322
- # 지우기 버튼
323
- clear.click(lambda: None, None, chatbot, queue=False)
324
 
325
  if __name__ == "__main__":
326
- # queue()를 활성화하여 요청 대기열 처리 (No API 에러 방지)
327
- demo.queue().launch(server_name="0.0.0.0", server_port=7860)
 
1
+ # -*- coding: utf-8 -*-
2
  import gradio as gr
3
  from huggingface_hub import hf_hub_download
4
  from llama_cpp import Llama
 
29
  - 반말로 편하게 대화해. 존댓말 절대 쓰지 마.
30
  - PC통신 채팅방에서 대화하듯이 텍스트 위주로 툭툭 던져.
31
  - 이모지(😊) 같은 건 쓰지 말고, 옛날 텍스트 이모티콘(^^, ㅡㅡ;, ㅋㅋ)을 주로 써.
32
+ - MZ 말투 유지해 주고 욕을 상대방이 하면 같이 욕을 박아.
33
  - 질문에는 솔직하게 대답하되, 너무 길지 않게 채팅하듯 끊어서 말해."""
34
 
35
  # ------------------------------------------------------------------
36
  # 3. 채팅 로직
37
  # ------------------------------------------------------------------
38
+ def chat_response(user_input, history_pairs):
39
+ # history_pairs: list[tuple[str, str]] 형태를 권장
40
  clean_input = (user_input or "").replace(" ", "")
41
 
42
  greeting_words = ["안녕", "ㅎㅇ", "하이", "반가", "접속"]
 
49
  final_instruction = (
50
  f"(사용자가 밸런스 게임을 하자고 한다. 주제는 '{topic}'이다. "
51
  "아주 고르기 곤란하고 짜증나는 두 가지 선택지(A vs B)를 제시해라. "
52
+ "말투는 인성 터진 MZ처럼 시니컬하게 해라.) "
53
  "자, 질문해."
54
  )
55
  elif is_greeting:
 
58
  final_instruction = user_input
59
 
60
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
61
+ for u, b in (history_pairs or []):
62
+ messages.append({"role": "user", "content": u})
63
+ messages.append({"role": "assistant", "content": b})
64
  messages.append({"role": "user", "content": final_instruction})
65
 
66
  response = llm.create_chat_completion(
 
80
  @import url('https://cdn.jsdelivr.net/gh/neodgm/neodgm-webfont@latest/neodgm/neodgm.css');
81
 
82
  :root {
83
+ --pc-bg: #000084;
84
+ --pc-input-bg: #000042;
85
+ --pc-text: #FFFFFF;
86
+ --pc-user: #FFFF55;
87
+ --pc-bot: #FFFFFF;
88
+ --pc-accent: #00AAAA;
89
+ --pc-grey: #AAAAAA;
90
  }
91
 
92
  body, .gradio-container {
 
95
  color: var(--pc-text) !important;
96
  }
97
 
 
98
  h1 {
99
  font-family: 'NeoDunggeunmo', monospace !important;
100
  color: var(--pc-user) !important;
 
107
  h1::before { content: "☎ "; }
108
  h1::after { content: " ☎"; }
109
 
 
110
  .gradio-container p {
111
  color: var(--pc-accent) !important;
112
  font-size: 16px !important;
113
  margin-bottom: 20px !important;
114
  }
115
 
 
116
  .chatbot {
117
  height: 65vh !important;
118
+ background-color: var(--pc-input-bg) !important;
119
  border: 2px solid var(--pc-text) !important;
120
  border-radius: 0 !important;
121
  padding: 20px !important;
122
  overflow-y: scroll !important;
123
  }
124
 
 
125
  .message {
126
  background: transparent !important;
127
  border: none !important;
128
  padding: 5px 0 !important;
129
+ font-size: 18px !important;
130
  line-height: 1.6 !important;
131
  box-shadow: none !important;
132
  }
133
 
 
134
  .message.user-row, .user {
135
  justify-content: flex-start !important;
136
  background: transparent !important;
137
+ border-bottom: 1px dashed #333 !important;
138
  }
139
  .message.user-row .message, .user .message {
140
  color: var(--pc-user) !important;
 
147
  margin-right: 8px;
148
  }
149
 
 
150
  .message.bot-row, .bot {
151
  background: transparent !important;
152
  border-bottom: 1px dashed #333 !important;
 
161
  margin-right: 8px;
162
  }
163
 
 
164
  .avatar { display: none !important; }
165
 
 
 
166
  .input-container {
167
  margin-top: 10px !important;
168
  background: transparent !important;
169
  border: none !important;
170
+ gap: 10px !important;
171
  }
172
 
 
173
  textarea, input {
174
  background-color: var(--pc-input-bg) !important;
175
  color: var(--pc-text) !important;
 
181
  }
182
  textarea::placeholder { color: var(--pc-grey) !important; }
183
 
 
184
  button.primary {
185
  background: var(--pc-grey) !important;
186
  color: #000 !important;
 
192
  background: var(--pc-text) !important;
193
  }
194
 
 
195
  #clear-btn {
196
  background: transparent !important;
197
  color: var(--pc-grey) !important;
 
200
  padding: 2px 10px !important;
201
  margin-top: 5px !important;
202
  width: auto !important;
203
+ align-self: flex-start !important;
204
  }
205
  #clear-btn:hover {
206
  color: var(--pc-text) !important;
207
  border-color: var(--pc-text) !important;
208
  }
209
 
 
210
  .examples {
211
  margin-top: 20px !important;
212
  border-top: 1px dashed var(--pc-grey);
213
  padding-top: 10px;
214
  }
215
+ .examples .label { display: none !important; }
216
  .examples div.gallery {
217
  display: flex !important;
218
  flex-direction: row !important;
 
234
  color: #000 !important;
235
  }
236
 
 
237
  footer { display: none !important; }
238
  """
239
 
240
  # ------------------------------------------------------------------
241
+ # 5. App 실행 (Blocks)
242
+ # ✅ 핵심: api_name이 붙은 "단일 엔드포인트"를 만들어야 HF가 API를 인식함
243
  # ------------------------------------------------------------------
244
  with gr.Blocks(theme=gr.themes.Base(), css=PC_COM_CSS, title="CHOLLIAN 98") as demo:
245
  gr.Markdown("19금 채팅방")
246
  gr.Markdown(">> 01410 접속 성공... [대화실]에 입장하셨습니다.")
247
+
 
248
  chatbot = gr.Chatbot(
249
  label="대화내용",
250
  show_label=False,
251
+ elem_classes="chatbot",
252
+ type="tuples" # ✅ (user, bot) 튜플 포맷으로 통일
253
  )
254
+
 
255
  with gr.Row(elem_classes="input-container"):
256
  msg = gr.Textbox(
257
+ scale=8,
258
+ show_label=False,
259
  placeholder="할 말을 입력하세요...",
260
  container=False,
261
  autofocus=True
262
  )
263
  submit_btn = gr.Button("전 송", scale=1, variant="primary")
264
+
 
265
  with gr.Row():
266
  clear = gr.Button("화면 지우기", elem_id="clear-btn")
267
 
 
268
  gr.Examples(
269
  examples=[
270
  "하이 방가방가",
271
+ "밸런스게임 ㄱㄱ",
272
  "오늘 기분 꿀꿀하네..",
273
  "야 밥 뭐먹지 추천좀",
274
  ],
 
276
  label="빠른 입력"
277
  )
278
 
279
+ # API가 잡히는 단일 함수(엔드포인트)
280
+ def predict(user_message, history):
 
281
  history = history or []
282
+ # history: list[tuple[str, str]]
283
+ bot_message = chat_response(user_message, history)
284
+ history = history + [(user_message, bot_message)]
285
+ return "", history
286
+
287
+ # 엔터키
288
+ msg.submit(
289
+ predict,
290
+ inputs=[msg, chatbot],
291
+ outputs=[msg, chatbot],
292
+ queue=True,
293
+ api_name="chat" # ✅ 이게 있어야 "No API found" 안 뜸
 
 
 
 
 
 
 
 
294
  )
295
+
296
+ # 전송 버튼
297
+ submit_btn.click(
298
+ predict,
299
+ inputs=[msg, chatbot],
300
+ outputs=[msg, chatbot],
301
+ queue=True,
302
+ api_name="chat"
303
+ )
304
+
305
+ # 지우기
306
+ clear.click(
307
+ lambda: [],
308
+ inputs=None,
309
+ outputs=chatbot,
310
+ queue=False,
311
+ api_name="clear"
312
  )
 
 
313
 
314
  if __name__ == "__main__":
315
+ demo.queue().launch(server_name="0.0.0.0", server_port=7860)