Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -2,6 +2,8 @@
|
|
2 |
import os
|
3 |
import gradio as gr
|
4 |
from gradio import ChatMessage
|
|
|
|
|
5 |
from huggingface_hub import HfApi
|
6 |
import requests
|
7 |
import re
|
@@ -9,9 +11,6 @@ import traceback
|
|
9 |
import time
|
10 |
import threading
|
11 |
import json
|
12 |
-
import asyncio
|
13 |
-
from typing import List, Dict, Tuple, Iterator
|
14 |
-
import google.generativeai as genai
|
15 |
|
16 |
# HuggingFace κ΄λ ¨ API ν€ (μ€νμ΄μ€ λΆμ μ©)
|
17 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
@@ -44,7 +43,6 @@ def get_file_content(space_id: str, file_path: str) -> str:
|
|
44 |
def get_space_structure(space_id: str) -> Dict:
|
45 |
try:
|
46 |
files = hf_api.list_repo_files(repo_id=space_id, repo_type="space")
|
47 |
-
|
48 |
tree = {"type": "directory", "path": "", "name": space_id, "children": []}
|
49 |
for file in files:
|
50 |
path_parts = file.split('/')
|
@@ -52,7 +50,7 @@ def get_space_structure(space_id: str) -> Dict:
|
|
52 |
for i, part in enumerate(path_parts):
|
53 |
if i == len(path_parts) - 1: # νμΌ
|
54 |
current["children"].append({"type": "file", "path": file, "name": part})
|
55 |
-
else:
|
56 |
found = False
|
57 |
for child in current["children"]:
|
58 |
if child["type"] == "directory" and child["name"] == part:
|
@@ -63,7 +61,6 @@ def get_space_structure(space_id: str) -> Dict:
|
|
63 |
new_dir = {"type": "directory", "path": '/'.join(path_parts[:i+1]), "name": part, "children": []}
|
64 |
current["children"].append(new_dir)
|
65 |
current = new_dir
|
66 |
-
|
67 |
return tree
|
68 |
except Exception as e:
|
69 |
print(f"Error in get_space_structure: {str(e)}")
|
@@ -72,7 +69,6 @@ def get_space_structure(space_id: str) -> Dict:
|
|
72 |
def format_tree_structure(tree_data: Dict, indent: str = "") -> str:
|
73 |
if "error" in tree_data:
|
74 |
return tree_data["error"]
|
75 |
-
|
76 |
formatted = f"{indent}{'π' if tree_data.get('type') == 'directory' else 'π'} {tree_data.get('name', 'Unknown')}\n"
|
77 |
if tree_data.get("type") == "directory":
|
78 |
for child in sorted(tree_data.get("children", []), key=lambda x: (x.get("type", "") != "directory", x.get("name", ""))):
|
@@ -80,47 +76,28 @@ def format_tree_structure(tree_data: Dict, indent: str = "") -> str:
|
|
80 |
return formatted
|
81 |
|
82 |
def adjust_lines_for_code(code_content: str, min_lines: int = 10, max_lines: int = 100) -> int:
|
83 |
-
"""
|
84 |
-
μ½λ λ΄μ©μ λ°λΌ lines μλ₯Ό λμ μΌλ‘ μ‘°μ ν©λλ€.
|
85 |
-
|
86 |
-
Parameters:
|
87 |
-
- code_content (str): μ½λ ν
μ€νΈ λ΄μ©
|
88 |
-
- min_lines (int): μ΅μ lines μ
|
89 |
-
- max_lines (int): μ΅λ lines μ
|
90 |
-
|
91 |
-
Returns:
|
92 |
-
- int: μ€μ λ lines μ
|
93 |
-
"""
|
94 |
num_lines = len(code_content.split('\n'))
|
95 |
return min(max(num_lines, min_lines), max_lines)
|
96 |
|
97 |
def analyze_space(url: str, progress=gr.Progress()):
|
98 |
try:
|
99 |
space_id = url.split('spaces/')[-1]
|
100 |
-
|
101 |
if not re.match(r'^[\w.-]+/[\w.-]+$', space_id):
|
102 |
raise ValueError(f"Invalid Space ID format: {space_id}")
|
103 |
-
|
104 |
progress(0.1, desc="νμΌ κ΅¬μ‘° λΆμ μ€...")
|
105 |
tree_structure = get_space_structure(space_id)
|
106 |
if "error" in tree_structure:
|
107 |
raise ValueError(tree_structure["error"])
|
108 |
tree_view = format_tree_structure(tree_structure)
|
109 |
-
|
110 |
progress(0.3, desc="app.py λ΄μ© κ°μ Έμ€λ μ€...")
|
111 |
app_content = get_file_content(space_id, "app.py")
|
112 |
-
|
113 |
progress(0.5, desc="μ½λ μμ½ μ€...")
|
114 |
summary = summarize_code(app_content)
|
115 |
-
|
116 |
progress(0.7, desc="μ½λ λΆμ μ€...")
|
117 |
analysis = analyze_code(app_content)
|
118 |
-
|
119 |
progress(0.9, desc="μ¬μ©λ² μ€λͺ
μμ± μ€...")
|
120 |
usage = explain_usage(app_content)
|
121 |
-
|
122 |
app_py_lines = adjust_lines_for_code(app_content)
|
123 |
-
|
124 |
progress(1.0, desc="μλ£")
|
125 |
return app_content, tree_view, tree_structure, space_id, summary, analysis, usage, app_py_lines
|
126 |
except Exception as e:
|
@@ -131,13 +108,10 @@ def analyze_space(url: str, progress=gr.Progress()):
|
|
131 |
# --------------------------------------------------
|
132 |
# Gemini 2.0 Flash Thinking λͺ¨λΈ κ΄λ ¨ ν¬νΌ ν¨μλ€
|
133 |
# --------------------------------------------------
|
134 |
-
def format_chat_history(messages:
|
135 |
-
"""
|
136 |
-
Gradio ChatMessage κ°μ²΄ 리μ€νΈλ₯Ό Geminiκ° μ΄ν΄ν μ μλ νμμΌλ‘ λ³νν©λλ€.
|
137 |
-
"""
|
138 |
formatted_history = []
|
139 |
for message in messages:
|
140 |
-
# thinking λ©μμ§(
|
141 |
if not (hasattr(message, "metadata") and message.metadata):
|
142 |
formatted_history.append({
|
143 |
"role": "user" if message.role == "user" else "assistant",
|
@@ -146,10 +120,6 @@ def format_chat_history(messages: list) -> list:
|
|
146 |
return formatted_history
|
147 |
|
148 |
def gemini_chat_completion(system_message: str, user_message: str, max_tokens: int = 200, temperature: float = 0.7) -> str:
|
149 |
-
"""
|
150 |
-
μμ€ν
λ° μ μ λ©μμ§λ₯Ό 보λ΄κ³ μ€νΈλ¦¬λ° μλ΅μ λμ νμ¬ μ΅μ’
ν
μ€νΈλ₯Ό λ°νν©λλ€.
|
151 |
-
"""
|
152 |
-
# μ΄κΈ° λν κΈ°λ‘ κ΅¬μ± (λ¨μ λ¬Έμμ΄ κΈ°λ°)
|
153 |
initial_messages = [
|
154 |
ChatMessage(role="system", content=system_message),
|
155 |
ChatMessage(role="user", content=user_message)
|
@@ -160,7 +130,6 @@ def gemini_chat_completion(system_message: str, user_message: str, max_tokens: i
|
|
160 |
try:
|
161 |
for chunk in chat.send_message(user_message, stream=True):
|
162 |
parts = chunk.candidates[0].content.parts
|
163 |
-
# μκ°(thinking) λΆλΆκ³Ό μ΅μ’
μλ΅ κ΅¬λΆμ΄ μλ€λ©΄ μ΅μ’
μλ΅μ μ¬μ©
|
164 |
if len(parts) == 2:
|
165 |
final_response += parts[1].text
|
166 |
else:
|
@@ -169,7 +138,7 @@ def gemini_chat_completion(system_message: str, user_message: str, max_tokens: i
|
|
169 |
except Exception as e:
|
170 |
return f"LLM νΈμΆ μ€ μ€λ₯ λ°μ: {str(e)}"
|
171 |
|
172 |
-
def summarize_code(app_content: str):
|
173 |
system_message = "λΉμ μ Python μ½λλ₯Ό λΆμνκ³ μμ½νλ AI μ‘°μμ
λλ€. μ£Όμ΄μ§ μ½λλ₯Ό 3μ€ μ΄λ΄λ‘ κ°κ²°νκ² μμ½ν΄μ£ΌμΈμ."
|
174 |
user_message = f"λ€μ Python μ½λλ₯Ό 3μ€ μ΄λ΄λ‘ μμ½ν΄μ£ΌμΈμ:\n\n{app_content}"
|
175 |
try:
|
@@ -177,7 +146,7 @@ def summarize_code(app_content: str):
|
|
177 |
except Exception as e:
|
178 |
return f"μμ½ μμ± μ€ μ€λ₯ λ°μ: {str(e)}"
|
179 |
|
180 |
-
def analyze_code(app_content: str):
|
181 |
system_message = (
|
182 |
"λΉμ μ Python μ½λλ₯Ό λΆμνλ AI μ‘°μμ
λλ€. μ£Όμ΄μ§ μ½λλ₯Ό λΆμνμ¬ λ€μ νλͺ©μ λν΄ μ€λͺ
ν΄μ£ΌμΈμ:\n"
|
183 |
"A. λ°°κ²½ λ° νμμ±\n"
|
@@ -193,7 +162,7 @@ def analyze_code(app_content: str):
|
|
193 |
except Exception as e:
|
194 |
return f"λΆμ μμ± μ€ μ€λ₯ λ°μ: {str(e)}"
|
195 |
|
196 |
-
def explain_usage(app_content: str):
|
197 |
system_message = "λΉμ μ Python μ½λλ₯Ό λΆμνμ¬ μ¬μ©λ²μ μ€λͺ
νλ AI μ‘°μμ
λλ€. μ£Όμ΄μ§ μ½λλ₯Ό λ°νμΌλ‘ λ§μΉ νλ©΄μ 보λ κ²μ²λΌ μ¬μ©λ²μ μμΈν μ€λͺ
ν΄μ£ΌμΈμ. Markdown νμμΌλ‘ μΆλ ₯νμΈμ."
|
198 |
user_message = f"λ€μ Python μ½λμ μ¬μ©λ²μ μ€λͺ
ν΄μ£ΌμΈμ:\n\n{app_content}"
|
199 |
try:
|
@@ -201,11 +170,28 @@ def explain_usage(app_content: str):
|
|
201 |
except Exception as e:
|
202 |
return f"μ¬μ©λ² μ€λͺ
μμ± μ€ μ€λ₯ λ°μ: {str(e)}"
|
203 |
|
204 |
-
def
|
205 |
"""
|
206 |
-
|
207 |
-
μ΄ ν¨μλ Gradioμ ChatMessage κ°μ²΄λ₯Ό μ¬μ©νλ©°, μ€μκ° 'thinking' λ° μ΅μ’
μλ΅μ 보μ¬μ€λλ€.
|
208 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
if not user_message.strip():
|
210 |
messages.append(ChatMessage(role="assistant", content="Please provide a non-empty text message. Empty input is not allowed."))
|
211 |
yield messages
|
@@ -214,17 +200,13 @@ def stream_gemini_response(user_message: str, messages: list) -> Iterator[list]:
|
|
214 |
try:
|
215 |
print(f"\n=== New Request (Text) ===")
|
216 |
print(f"User message: {user_message}")
|
217 |
-
|
218 |
-
# ν¬λ§·λ λν κΈ°λ‘ μμ±
|
219 |
chat_history = format_chat_history(messages)
|
220 |
chat = model.start_chat(history=chat_history)
|
221 |
response = chat.send_message(user_message, stream=True)
|
222 |
-
|
223 |
thought_buffer = ""
|
224 |
response_buffer = ""
|
225 |
thinking_complete = False
|
226 |
|
227 |
-
# μ΄κΈ° 'thinking' λ©μμ§ μΆκ°
|
228 |
messages.append(
|
229 |
ChatMessage(
|
230 |
role="assistant",
|
@@ -240,7 +222,6 @@ def stream_gemini_response(user_message: str, messages: list) -> Iterator[list]:
|
|
240 |
if len(parts) == 2 and not thinking_complete:
|
241 |
thought_buffer += current_chunk
|
242 |
print(f"\n=== Complete Thought ===\n{thought_buffer}")
|
243 |
-
|
244 |
messages[-1] = ChatMessage(
|
245 |
role="assistant",
|
246 |
content=thought_buffer,
|
@@ -250,7 +231,6 @@ def stream_gemini_response(user_message: str, messages: list) -> Iterator[list]:
|
|
250 |
|
251 |
response_buffer = parts[1].text
|
252 |
print(f"\n=== Starting Response ===\n{response_buffer}")
|
253 |
-
|
254 |
messages.append(
|
255 |
ChatMessage(
|
256 |
role="assistant",
|
@@ -262,7 +242,6 @@ def stream_gemini_response(user_message: str, messages: list) -> Iterator[list]:
|
|
262 |
elif thinking_complete:
|
263 |
response_buffer += current_chunk
|
264 |
print(f"\n=== Response Chunk ===\n{current_chunk}")
|
265 |
-
|
266 |
messages[-1] = ChatMessage(
|
267 |
role="assistant",
|
268 |
content=response_buffer
|
@@ -271,7 +250,6 @@ def stream_gemini_response(user_message: str, messages: list) -> Iterator[list]:
|
|
271 |
else:
|
272 |
thought_buffer += current_chunk
|
273 |
print(f"\n=== Thinking Chunk ===\n{current_chunk}")
|
274 |
-
|
275 |
messages[-1] = ChatMessage(
|
276 |
role="assistant",
|
277 |
content=thought_buffer,
|
@@ -291,11 +269,16 @@ def stream_gemini_response(user_message: str, messages: list) -> Iterator[list]:
|
|
291 |
)
|
292 |
yield messages
|
293 |
|
294 |
-
def respond(message: str, history:
|
295 |
"""
|
296 |
-
|
297 |
"""
|
298 |
-
|
|
|
|
|
|
|
|
|
|
|
299 |
|
300 |
# --------------------------------------------------
|
301 |
# Gradio UI ꡬμ±
|
@@ -421,9 +404,11 @@ def create_ui():
|
|
421 |
)
|
422 |
|
423 |
with gr.TabItem("AI μ½λ©"):
|
|
|
424 |
chatbot = gr.Chatbot(
|
425 |
label="λν",
|
426 |
-
elem_classes="output-group
|
|
|
427 |
)
|
428 |
|
429 |
msg = gr.Textbox(label="λ©μμ§", placeholder="λ©μμ§λ₯Ό μ
λ ₯νμΈμ...")
|
@@ -444,8 +429,9 @@ def create_ui():
|
|
444 |
gr.Examples(examples, inputs=msg)
|
445 |
|
446 |
def respond_wrapper(message, chat_history, max_tokens, temperature, top_p):
|
447 |
-
#
|
448 |
-
|
|
|
449 |
|
450 |
msg.submit(respond_wrapper, [msg, chatbot, max_tokens, temperature, top_p], [msg, chatbot])
|
451 |
|
@@ -484,11 +470,9 @@ if __name__ == "__main__":
|
|
484 |
print("Starting HuggingFace Space Analyzer...")
|
485 |
demo = create_ui()
|
486 |
print("UI created successfully.")
|
487 |
-
|
488 |
print("Configuring Gradio queue...")
|
489 |
demo.queue()
|
490 |
print("Gradio queue configured.")
|
491 |
-
|
492 |
print("Launching Gradio app...")
|
493 |
demo.launch(
|
494 |
server_name="0.0.0.0",
|
|
|
2 |
import os
|
3 |
import gradio as gr
|
4 |
from gradio import ChatMessage
|
5 |
+
from typing import Iterator, List, Dict, Tuple
|
6 |
+
import google.generativeai as genai
|
7 |
from huggingface_hub import HfApi
|
8 |
import requests
|
9 |
import re
|
|
|
11 |
import time
|
12 |
import threading
|
13 |
import json
|
|
|
|
|
|
|
14 |
|
15 |
# HuggingFace κ΄λ ¨ API ν€ (μ€νμ΄μ€ λΆμ μ©)
|
16 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
|
|
43 |
def get_space_structure(space_id: str) -> Dict:
|
44 |
try:
|
45 |
files = hf_api.list_repo_files(repo_id=space_id, repo_type="space")
|
|
|
46 |
tree = {"type": "directory", "path": "", "name": space_id, "children": []}
|
47 |
for file in files:
|
48 |
path_parts = file.split('/')
|
|
|
50 |
for i, part in enumerate(path_parts):
|
51 |
if i == len(path_parts) - 1: # νμΌ
|
52 |
current["children"].append({"type": "file", "path": file, "name": part})
|
53 |
+
else:
|
54 |
found = False
|
55 |
for child in current["children"]:
|
56 |
if child["type"] == "directory" and child["name"] == part:
|
|
|
61 |
new_dir = {"type": "directory", "path": '/'.join(path_parts[:i+1]), "name": part, "children": []}
|
62 |
current["children"].append(new_dir)
|
63 |
current = new_dir
|
|
|
64 |
return tree
|
65 |
except Exception as e:
|
66 |
print(f"Error in get_space_structure: {str(e)}")
|
|
|
69 |
def format_tree_structure(tree_data: Dict, indent: str = "") -> str:
|
70 |
if "error" in tree_data:
|
71 |
return tree_data["error"]
|
|
|
72 |
formatted = f"{indent}{'π' if tree_data.get('type') == 'directory' else 'π'} {tree_data.get('name', 'Unknown')}\n"
|
73 |
if tree_data.get("type") == "directory":
|
74 |
for child in sorted(tree_data.get("children", []), key=lambda x: (x.get("type", "") != "directory", x.get("name", ""))):
|
|
|
76 |
return formatted
|
77 |
|
78 |
def adjust_lines_for_code(code_content: str, min_lines: int = 10, max_lines: int = 100) -> int:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
num_lines = len(code_content.split('\n'))
|
80 |
return min(max(num_lines, min_lines), max_lines)
|
81 |
|
82 |
def analyze_space(url: str, progress=gr.Progress()):
|
83 |
try:
|
84 |
space_id = url.split('spaces/')[-1]
|
|
|
85 |
if not re.match(r'^[\w.-]+/[\w.-]+$', space_id):
|
86 |
raise ValueError(f"Invalid Space ID format: {space_id}")
|
|
|
87 |
progress(0.1, desc="νμΌ κ΅¬μ‘° λΆμ μ€...")
|
88 |
tree_structure = get_space_structure(space_id)
|
89 |
if "error" in tree_structure:
|
90 |
raise ValueError(tree_structure["error"])
|
91 |
tree_view = format_tree_structure(tree_structure)
|
|
|
92 |
progress(0.3, desc="app.py λ΄μ© κ°μ Έμ€λ μ€...")
|
93 |
app_content = get_file_content(space_id, "app.py")
|
|
|
94 |
progress(0.5, desc="μ½λ μμ½ μ€...")
|
95 |
summary = summarize_code(app_content)
|
|
|
96 |
progress(0.7, desc="μ½λ λΆμ μ€...")
|
97 |
analysis = analyze_code(app_content)
|
|
|
98 |
progress(0.9, desc="μ¬μ©λ² μ€λͺ
μμ± μ€...")
|
99 |
usage = explain_usage(app_content)
|
|
|
100 |
app_py_lines = adjust_lines_for_code(app_content)
|
|
|
101 |
progress(1.0, desc="μλ£")
|
102 |
return app_content, tree_view, tree_structure, space_id, summary, analysis, usage, app_py_lines
|
103 |
except Exception as e:
|
|
|
108 |
# --------------------------------------------------
|
109 |
# Gemini 2.0 Flash Thinking λͺ¨λΈ κ΄λ ¨ ν¬νΌ ν¨μλ€
|
110 |
# --------------------------------------------------
|
111 |
+
def format_chat_history(messages: List[ChatMessage]) -> List[Dict]:
|
|
|
|
|
|
|
112 |
formatted_history = []
|
113 |
for message in messages:
|
114 |
+
# thinking λ©μμ§(λ©νλ°μ΄ν° μλ λ©μμ§)λ 건λλλλ€.
|
115 |
if not (hasattr(message, "metadata") and message.metadata):
|
116 |
formatted_history.append({
|
117 |
"role": "user" if message.role == "user" else "assistant",
|
|
|
120 |
return formatted_history
|
121 |
|
122 |
def gemini_chat_completion(system_message: str, user_message: str, max_tokens: int = 200, temperature: float = 0.7) -> str:
|
|
|
|
|
|
|
|
|
123 |
initial_messages = [
|
124 |
ChatMessage(role="system", content=system_message),
|
125 |
ChatMessage(role="user", content=user_message)
|
|
|
130 |
try:
|
131 |
for chunk in chat.send_message(user_message, stream=True):
|
132 |
parts = chunk.candidates[0].content.parts
|
|
|
133 |
if len(parts) == 2:
|
134 |
final_response += parts[1].text
|
135 |
else:
|
|
|
138 |
except Exception as e:
|
139 |
return f"LLM νΈμΆ μ€ μ€λ₯ λ°μ: {str(e)}"
|
140 |
|
141 |
+
def summarize_code(app_content: str) -> str:
|
142 |
system_message = "λΉμ μ Python μ½λλ₯Ό λΆμνκ³ μμ½νλ AI μ‘°μμ
λλ€. μ£Όμ΄μ§ μ½λλ₯Ό 3μ€ μ΄λ΄λ‘ κ°κ²°νκ² μμ½ν΄μ£ΌμΈμ."
|
143 |
user_message = f"λ€μ Python μ½λλ₯Ό 3μ€ μ΄λ΄λ‘ μμ½ν΄μ£ΌμΈμ:\n\n{app_content}"
|
144 |
try:
|
|
|
146 |
except Exception as e:
|
147 |
return f"μμ½ μμ± μ€ μ€λ₯ λ°μ: {str(e)}"
|
148 |
|
149 |
+
def analyze_code(app_content: str) -> str:
|
150 |
system_message = (
|
151 |
"λΉμ μ Python μ½λλ₯Ό λΆμνλ AI μ‘°μμ
λλ€. μ£Όμ΄μ§ μ½λλ₯Ό λΆμνμ¬ λ€μ νλͺ©μ λν΄ μ€λͺ
ν΄μ£ΌμΈμ:\n"
|
152 |
"A. λ°°κ²½ λ° νμμ±\n"
|
|
|
162 |
except Exception as e:
|
163 |
return f"λΆμ μμ± μ€ μ€λ₯ λ°μ: {str(e)}"
|
164 |
|
165 |
+
def explain_usage(app_content: str) -> str:
|
166 |
system_message = "λΉμ μ Python μ½λλ₯Ό λΆμνμ¬ μ¬μ©λ²μ μ€λͺ
νλ AI μ‘°μμ
λλ€. μ£Όμ΄μ§ μ½λλ₯Ό λ°νμΌλ‘ λ§μΉ νλ©΄μ 보λ κ²μ²λΌ μ¬μ©λ²μ μμΈν μ€λͺ
ν΄μ£ΌμΈμ. Markdown νμμΌλ‘ μΆλ ₯νμΈμ."
|
167 |
user_message = f"λ€μ Python μ½λμ μ¬μ©λ²μ μ€λͺ
ν΄μ£ΌμΈμ:\n\n{app_content}"
|
168 |
try:
|
|
|
170 |
except Exception as e:
|
171 |
return f"μ¬μ©λ² μ€λͺ
μμ± μ€ μ€λ₯ λ°μ: {str(e)}"
|
172 |
|
173 |
+
def convert_chat_history(messages: List[ChatMessage]) -> List[Tuple[str, str]]:
|
174 |
"""
|
175 |
+
ChatMessage κ°μ²΄ 리μ€νΈλ₯Ό (user, assistant) νν λͺ©λ‘μΌλ‘ λ³νν©λλ€.
|
|
|
176 |
"""
|
177 |
+
conv = []
|
178 |
+
i = 0
|
179 |
+
while i < len(messages):
|
180 |
+
if messages[i].role == "user":
|
181 |
+
user_text = messages[i].content
|
182 |
+
bot_text = ""
|
183 |
+
if i + 1 < len(messages) and messages[i+1].role == "assistant":
|
184 |
+
bot_text = messages[i+1].content
|
185 |
+
i += 2
|
186 |
+
else:
|
187 |
+
i += 1
|
188 |
+
conv.append((user_text, bot_text))
|
189 |
+
else:
|
190 |
+
conv.append(("", messages[i].content))
|
191 |
+
i += 1
|
192 |
+
return conv
|
193 |
+
|
194 |
+
def stream_gemini_response(user_message: str, messages: List[ChatMessage]) -> Iterator[List[ChatMessage]]:
|
195 |
if not user_message.strip():
|
196 |
messages.append(ChatMessage(role="assistant", content="Please provide a non-empty text message. Empty input is not allowed."))
|
197 |
yield messages
|
|
|
200 |
try:
|
201 |
print(f"\n=== New Request (Text) ===")
|
202 |
print(f"User message: {user_message}")
|
|
|
|
|
203 |
chat_history = format_chat_history(messages)
|
204 |
chat = model.start_chat(history=chat_history)
|
205 |
response = chat.send_message(user_message, stream=True)
|
|
|
206 |
thought_buffer = ""
|
207 |
response_buffer = ""
|
208 |
thinking_complete = False
|
209 |
|
|
|
210 |
messages.append(
|
211 |
ChatMessage(
|
212 |
role="assistant",
|
|
|
222 |
if len(parts) == 2 and not thinking_complete:
|
223 |
thought_buffer += current_chunk
|
224 |
print(f"\n=== Complete Thought ===\n{thought_buffer}")
|
|
|
225 |
messages[-1] = ChatMessage(
|
226 |
role="assistant",
|
227 |
content=thought_buffer,
|
|
|
231 |
|
232 |
response_buffer = parts[1].text
|
233 |
print(f"\n=== Starting Response ===\n{response_buffer}")
|
|
|
234 |
messages.append(
|
235 |
ChatMessage(
|
236 |
role="assistant",
|
|
|
242 |
elif thinking_complete:
|
243 |
response_buffer += current_chunk
|
244 |
print(f"\n=== Response Chunk ===\n{current_chunk}")
|
|
|
245 |
messages[-1] = ChatMessage(
|
246 |
role="assistant",
|
247 |
content=response_buffer
|
|
|
250 |
else:
|
251 |
thought_buffer += current_chunk
|
252 |
print(f"\n=== Thinking Chunk ===\n{current_chunk}")
|
|
|
253 |
messages[-1] = ChatMessage(
|
254 |
role="assistant",
|
255 |
content=thought_buffer,
|
|
|
269 |
)
|
270 |
yield messages
|
271 |
|
272 |
+
def respond(message: str, history: List[ChatMessage]) -> Iterator[List[Tuple[str, str]]]:
|
273 |
"""
|
274 |
+
κΈ°μ‘΄μ stream_gemini_response()λ₯Ό νΈμΆν ν, μΆλ ₯ κ²°κ³Όλ₯Ό νν λͺ©λ‘μΌλ‘ λ³ννμ¬ λ°νν©λλ€.
|
275 |
"""
|
276 |
+
for updated_messages in stream_gemini_response(message, history):
|
277 |
+
yield convert_chat_history(updated_messages)
|
278 |
+
|
279 |
+
def user_message(msg: str, history: List[ChatMessage]) -> Tuple[str, List[ChatMessage]]:
|
280 |
+
history.append(ChatMessage(role="user", content=msg))
|
281 |
+
return "", history
|
282 |
|
283 |
# --------------------------------------------------
|
284 |
# Gradio UI ꡬμ±
|
|
|
404 |
)
|
405 |
|
406 |
with gr.TabItem("AI μ½λ©"):
|
407 |
+
# μ±ν
λ°μ€ λμ΄λ₯Ό 400pxλ‘ μ§μ νμ¬ νλ©΄ λμ΄μ λ§κ² μ€μ.
|
408 |
chatbot = gr.Chatbot(
|
409 |
label="λν",
|
410 |
+
elem_classes="output-group",
|
411 |
+
height=400
|
412 |
)
|
413 |
|
414 |
msg = gr.Textbox(label="λ©μμ§", placeholder="λ©μμ§λ₯Ό μ
λ ₯νμΈμ...")
|
|
|
429 |
gr.Examples(examples, inputs=msg)
|
430 |
|
431 |
def respond_wrapper(message, chat_history, max_tokens, temperature, top_p):
|
432 |
+
# λ°νλλ μ λλ μ΄ν°μ κ° λ¨κ³λ§λ€ μ±ν
κΈ°λ‘μ νν λͺ©λ‘μΌλ‘ λ³νν©λλ€.
|
433 |
+
for updated in stream_gemini_response(message, chat_history):
|
434 |
+
yield "", convert_chat_history(updated)
|
435 |
|
436 |
msg.submit(respond_wrapper, [msg, chatbot, max_tokens, temperature, top_p], [msg, chatbot])
|
437 |
|
|
|
470 |
print("Starting HuggingFace Space Analyzer...")
|
471 |
demo = create_ui()
|
472 |
print("UI created successfully.")
|
|
|
473 |
print("Configuring Gradio queue...")
|
474 |
demo.queue()
|
475 |
print("Gradio queue configured.")
|
|
|
476 |
print("Launching Gradio app...")
|
477 |
demo.launch(
|
478 |
server_name="0.0.0.0",
|