|
|
import gradio as gr |
|
|
import httpx |
|
|
import asyncio |
|
|
import json |
|
|
from typing import Generator |
|
|
|
|
|
|
|
|
API_BASE_URL = "https://vidraft-kt.hf.space" |
|
|
|
|
|
|
|
|
current_session = {"session_id": None, "user_email": None} |
|
|
|
|
|
|
|
|
async def create_session(user_email: str) -> str: |
|
|
"""์ ์ธ์
์์ฑ""" |
|
|
if not user_email: |
|
|
return "โ ์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์." |
|
|
|
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=30.0) as client: |
|
|
response = await client.post( |
|
|
f"{API_BASE_URL}/session/new", |
|
|
json={"user_email": user_email} |
|
|
) |
|
|
result = response.json() |
|
|
|
|
|
if "error" in result: |
|
|
return f"โ ์ค๋ฅ: {result['error']}" |
|
|
|
|
|
current_session["session_id"] = result.get("session_id") |
|
|
current_session["user_email"] = user_email |
|
|
return f"โ
์ธ์
์์ฑ ์๋ฃ!\n์ธ์
ID: {result.get('session_id')}" |
|
|
except Exception as e: |
|
|
return f"โ ์ฐ๊ฒฐ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
async def end_session(session_id: str, user_email: str) -> str: |
|
|
"""์ธ์
์ข
๋ฃ""" |
|
|
if not session_id or not user_email: |
|
|
return "โ ์ธ์
ID์ ์ด๋ฉ์ผ์ด ํ์ํฉ๋๋ค." |
|
|
|
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=30.0) as client: |
|
|
response = await client.post( |
|
|
f"{API_BASE_URL}/session/end", |
|
|
json={"session_id": session_id, "user_email": user_email} |
|
|
) |
|
|
result = response.json() |
|
|
return f"โ
์ธ์
์ข
๋ฃ ์๋ฃ: {json.dumps(result, ensure_ascii=False, indent=2)}" |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
def chat_streaming(message: str, user_email: str, session_id: str, |
|
|
web_search: bool, self_learning: bool, history: list) -> Generator: |
|
|
"""์คํธ๋ฆฌ๋ฐ ์ฑํ
- messages ํ์ ์ฌ์ฉ (๋์
๋๋ฆฌ)""" |
|
|
if not user_email: |
|
|
history = history or [] |
|
|
history.append({"role": "assistant", "content": "โ ์ด๋ฉ์ผ์ ๋จผ์ ์
๋ ฅํด์ฃผ์ธ์."}) |
|
|
yield history |
|
|
return |
|
|
|
|
|
if not session_id: |
|
|
history = history or [] |
|
|
history.append({"role": "assistant", "content": "โ ์ธ์
์ ๋จผ์ ์์ฑํด์ฃผ์ธ์."}) |
|
|
yield history |
|
|
return |
|
|
|
|
|
|
|
|
history = history or [] |
|
|
history.append({"role": "user", "content": message}) |
|
|
history.append({"role": "assistant", "content": ""}) |
|
|
yield history |
|
|
|
|
|
|
|
|
full_response = "" |
|
|
try: |
|
|
with httpx.Client(timeout=120.0) as client: |
|
|
with client.stream( |
|
|
"POST", |
|
|
f"{API_BASE_URL}/chat/text/stream", |
|
|
json={ |
|
|
"message": message, |
|
|
"user_email": user_email, |
|
|
"session_id": session_id, |
|
|
"web_search_enabled": web_search, |
|
|
"self_learning_enabled": self_learning |
|
|
} |
|
|
) as response: |
|
|
for line in response.iter_lines(): |
|
|
if line.startswith("data: "): |
|
|
data = line[6:] |
|
|
if data == "[DONE]": |
|
|
break |
|
|
try: |
|
|
chunk = json.loads(data) |
|
|
content = chunk.get("content", "") |
|
|
full_response += content |
|
|
history[-1]["content"] = full_response |
|
|
yield history |
|
|
except json.JSONDecodeError: |
|
|
continue |
|
|
except Exception as e: |
|
|
history[-1]["content"] = f"โ ์ค๋ฅ: {str(e)}" |
|
|
yield history |
|
|
|
|
|
|
|
|
async def get_health_current(user_email: str) -> str: |
|
|
"""ํ์ฌ ๊ฑด๊ฐ ์ํ ์กฐํ""" |
|
|
if not user_email: |
|
|
return "โ ์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์." |
|
|
|
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=30.0) as client: |
|
|
response = await client.get( |
|
|
f"{API_BASE_URL}/health/current", |
|
|
params={"user_email": user_email} |
|
|
) |
|
|
result = response.json() |
|
|
return json.dumps(result, ensure_ascii=False, indent=2) |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
async def get_health_history(user_email: str, days: int) -> str: |
|
|
"""๊ฑด๊ฐ ํ์คํ ๋ฆฌ ์กฐํ""" |
|
|
if not user_email: |
|
|
return "โ ์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์." |
|
|
|
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=30.0) as client: |
|
|
response = await client.get( |
|
|
f"{API_BASE_URL}/health/history", |
|
|
params={"user_email": user_email, "days": days} |
|
|
) |
|
|
result = response.json() |
|
|
return json.dumps(result, ensure_ascii=False, indent=2) |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
async def search_memories(query: str, user_email: str, k: int, threshold: float) -> str: |
|
|
"""๊ธฐ์ต ๊ฒ์""" |
|
|
if not user_email or not query: |
|
|
return "โ ์ด๋ฉ์ผ๊ณผ ๊ฒ์์ด๋ฅผ ์
๋ ฅํด์ฃผ์ธ์." |
|
|
|
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=30.0) as client: |
|
|
response = await client.post( |
|
|
f"{API_BASE_URL}/memory/search", |
|
|
json={ |
|
|
"query": query, |
|
|
"user_email": user_email, |
|
|
"k": k, |
|
|
"threshold": threshold |
|
|
} |
|
|
) |
|
|
result = response.json() |
|
|
return json.dumps(result, ensure_ascii=False, indent=2) |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
async def get_all_memories(user_email: str) -> str: |
|
|
"""๋ชจ๋ ๊ธฐ์ต ์กฐํ""" |
|
|
if not user_email: |
|
|
return "โ ์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์." |
|
|
|
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=30.0) as client: |
|
|
response = await client.get( |
|
|
f"{API_BASE_URL}/memory/all", |
|
|
params={"user_email": user_email} |
|
|
) |
|
|
result = response.json() |
|
|
return json.dumps(result, ensure_ascii=False, indent=2) |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
async def delete_memory(memory_id: int, user_email: str) -> str: |
|
|
"""๊ธฐ์ต ์ญ์ """ |
|
|
if not user_email or not memory_id: |
|
|
return "โ ์ด๋ฉ์ผ๊ณผ ๊ธฐ์ต ID๋ฅผ ์
๋ ฅํด์ฃผ์ธ์." |
|
|
|
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=30.0) as client: |
|
|
response = await client.delete( |
|
|
f"{API_BASE_URL}/memory/{int(memory_id)}", |
|
|
params={"user_email": user_email} |
|
|
) |
|
|
result = response.json() |
|
|
return f"โ
์ญ์ ์๋ฃ: {json.dumps(result, ensure_ascii=False)}" |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
async def web_search(query: str, count: int) -> str: |
|
|
"""์น ๊ฒ์""" |
|
|
if not query: |
|
|
return "โ ๊ฒ์์ด๋ฅผ ์
๋ ฅํด์ฃผ์ธ์." |
|
|
|
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=30.0) as client: |
|
|
response = await client.post( |
|
|
f"{API_BASE_URL}/search/web", |
|
|
json={"query": query, "count": count} |
|
|
) |
|
|
result = response.json() |
|
|
return json.dumps(result, ensure_ascii=False, indent=2) |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
async def crawl_url(url: str) -> str: |
|
|
"""URL ํฌ๋กค๋ง""" |
|
|
if not url: |
|
|
return "โ URL์ ์
๋ ฅํด์ฃผ์ธ์." |
|
|
|
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=60.0) as client: |
|
|
response = await client.post( |
|
|
f"{API_BASE_URL}/crawl/url", |
|
|
json={"url": url} |
|
|
) |
|
|
result = response.json() |
|
|
return json.dumps(result, ensure_ascii=False, indent=2) |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
async def get_storage_info() -> str: |
|
|
"""์คํ ๋ฆฌ์ง ์ ๋ณด ์กฐํ""" |
|
|
try: |
|
|
async with httpx.AsyncClient(timeout=30.0) as client: |
|
|
response = await client.get(f"{API_BASE_URL}/storage/info") |
|
|
result = response.json() |
|
|
return json.dumps(result, ensure_ascii=False, indent=2) |
|
|
except Exception as e: |
|
|
return f"โ ์ค๋ฅ: {str(e)}" |
|
|
|
|
|
|
|
|
|
|
|
with gr.Blocks(title="KT API ํ
์คํธ") as demo: |
|
|
gr.Markdown("# ๐งช KT ์๋์ด AI ๋น์ API ํ
์คํธ") |
|
|
gr.Markdown(f"**API URL:** `{API_BASE_URL}`") |
|
|
|
|
|
with gr.Tabs(): |
|
|
|
|
|
with gr.TabItem("๐ฌ ์ฑํ
"): |
|
|
with gr.Row(): |
|
|
with gr.Column(scale=1): |
|
|
email_input = gr.Textbox(label="์ด๋ฉ์ผ (ํ์)", placeholder="test@example.com") |
|
|
session_input = gr.Textbox(label="์ธ์
ID", placeholder="์ธ์
์์ฑ ํ ์๋ ์
๋ ฅ๋จ") |
|
|
|
|
|
with gr.Row(): |
|
|
create_btn = gr.Button("๐ ์ธ์
์์ฑ", variant="primary") |
|
|
end_btn = gr.Button("๐ ์ธ์
์ข
๋ฃ") |
|
|
|
|
|
session_result = gr.Textbox(label="์ธ์
๊ฒฐ๊ณผ", lines=3) |
|
|
|
|
|
web_search_check = gr.Checkbox(label="์น ๊ฒ์ ํ์ฑํ", value=True) |
|
|
self_learning_check = gr.Checkbox(label="์๊ฐ ํ์ต ํ์ฑํ", value=True) |
|
|
|
|
|
with gr.Column(scale=2): |
|
|
|
|
|
chatbot = gr.Chatbot(label="๋ํ", height=400) |
|
|
msg_input = gr.Textbox(label="๋ฉ์์ง ์
๋ ฅ", placeholder="๋ฉ์์ง๋ฅผ ์
๋ ฅํ์ธ์...") |
|
|
send_btn = gr.Button("์ ์ก", variant="primary") |
|
|
|
|
|
|
|
|
async def on_create_session(email): |
|
|
result = await create_session(email) |
|
|
session_id = current_session.get("session_id", "") |
|
|
return result, session_id |
|
|
|
|
|
create_btn.click( |
|
|
on_create_session, |
|
|
inputs=[email_input], |
|
|
outputs=[session_result, session_input] |
|
|
) |
|
|
|
|
|
|
|
|
end_btn.click( |
|
|
end_session, |
|
|
inputs=[session_input, email_input], |
|
|
outputs=[session_result] |
|
|
) |
|
|
|
|
|
|
|
|
send_btn.click( |
|
|
chat_streaming, |
|
|
inputs=[msg_input, email_input, session_input, web_search_check, self_learning_check, chatbot], |
|
|
outputs=[chatbot] |
|
|
).then(lambda: "", outputs=[msg_input]) |
|
|
|
|
|
msg_input.submit( |
|
|
chat_streaming, |
|
|
inputs=[msg_input, email_input, session_input, web_search_check, self_learning_check, chatbot], |
|
|
outputs=[chatbot] |
|
|
).then(lambda: "", outputs=[msg_input]) |
|
|
|
|
|
|
|
|
with gr.TabItem("๐ฅ ๊ฑด๊ฐ ์ํ"): |
|
|
health_email = gr.Textbox(label="์ด๋ฉ์ผ", placeholder="test@example.com") |
|
|
|
|
|
with gr.Row(): |
|
|
health_current_btn = gr.Button("ํ์ฌ ๊ฑด๊ฐ ์ํ ์กฐํ", variant="primary") |
|
|
health_days = gr.Slider(1, 90, value=30, step=1, label="ํ์คํ ๋ฆฌ ์ผ์") |
|
|
health_history_btn = gr.Button("๊ฑด๊ฐ ํ์คํ ๋ฆฌ ์กฐํ") |
|
|
|
|
|
health_result = gr.Textbox(label="๊ฒฐ๊ณผ", lines=15) |
|
|
|
|
|
health_current_btn.click(get_health_current, inputs=[health_email], outputs=[health_result]) |
|
|
health_history_btn.click(get_health_history, inputs=[health_email, health_days], outputs=[health_result]) |
|
|
|
|
|
|
|
|
with gr.TabItem("๐ง ๊ธฐ์ต ๊ด๋ฆฌ"): |
|
|
memory_email = gr.Textbox(label="์ด๋ฉ์ผ", placeholder="test@example.com") |
|
|
|
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
gr.Markdown("### ๊ธฐ์ต ๊ฒ์") |
|
|
search_query = gr.Textbox(label="๊ฒ์์ด") |
|
|
search_k = gr.Slider(1, 50, value=10, step=1, label="๊ฒฐ๊ณผ ๊ฐ์") |
|
|
search_threshold = gr.Slider(0.1, 1.0, value=0.7, step=0.1, label="์ ์ฌ๋ ์๊ณ๊ฐ") |
|
|
search_btn = gr.Button("๊ฒ์", variant="primary") |
|
|
|
|
|
with gr.Column(): |
|
|
gr.Markdown("### ๊ธฐ์ต ์ญ์ ") |
|
|
delete_id = gr.Number(label="๊ธฐ์ต ID", precision=0) |
|
|
delete_btn = gr.Button("์ญ์ ", variant="stop") |
|
|
get_all_btn = gr.Button("๋ชจ๋ ๊ธฐ์ต ์กฐํ") |
|
|
|
|
|
memory_result = gr.Textbox(label="๊ฒฐ๊ณผ", lines=15) |
|
|
|
|
|
search_btn.click(search_memories, inputs=[search_query, memory_email, search_k, search_threshold], outputs=[memory_result]) |
|
|
get_all_btn.click(get_all_memories, inputs=[memory_email], outputs=[memory_result]) |
|
|
delete_btn.click(delete_memory, inputs=[delete_id, memory_email], outputs=[memory_result]) |
|
|
|
|
|
|
|
|
with gr.TabItem("๐ ์น ๊ฒ์"): |
|
|
with gr.Row(): |
|
|
with gr.Column(): |
|
|
gr.Markdown("### ์น ๊ฒ์") |
|
|
web_query = gr.Textbox(label="๊ฒ์์ด") |
|
|
web_count = gr.Slider(1, 20, value=10, step=1, label="๊ฒฐ๊ณผ ๊ฐ์") |
|
|
web_search_btn = gr.Button("๊ฒ์", variant="primary") |
|
|
|
|
|
with gr.Column(): |
|
|
gr.Markdown("### URL ํฌ๋กค๋ง") |
|
|
crawl_url_input = gr.Textbox(label="URL", placeholder="https://example.com") |
|
|
crawl_btn = gr.Button("ํฌ๋กค๋ง", variant="primary") |
|
|
|
|
|
web_result = gr.Textbox(label="๊ฒฐ๊ณผ", lines=15) |
|
|
|
|
|
web_search_btn.click(web_search, inputs=[web_query, web_count], outputs=[web_result]) |
|
|
crawl_btn.click(crawl_url, inputs=[crawl_url_input], outputs=[web_result]) |
|
|
|
|
|
|
|
|
with gr.TabItem("โ๏ธ ์์คํ
"): |
|
|
storage_btn = gr.Button("์คํ ๋ฆฌ์ง ์ ๋ณด ์กฐํ", variant="primary") |
|
|
storage_result = gr.Textbox(label="๊ฒฐ๊ณผ", lines=15) |
|
|
|
|
|
storage_btn.click(get_storage_info, outputs=[storage_result]) |
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch(server_name="0.0.0.0", server_port=7860) |