File size: 2,857 Bytes
48256af
805c338
ee792da
 
 
 
 
 
 
 
 
 
805c338
 
 
 
c2bc4f5
48256af
 
 
9fa8c49
81bdbe3
805c338
9c11986
0aab023
9fa8c49
9c11986
81bdbe3
0aab023
 
 
9c11986
81bdbe3
 
 
0aab023
fa08243
805c338
 
 
 
 
 
0aab023
 
 
 
 
 
d46feab
0aab023
805c338
0aab023
805c338
 
 
 
 
 
 
 
 
 
 
0aab023
 
6317980
d46feab
a7769f3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import os, json, requests, gradio as gr
# --- 修補 Gradio‑client 5.0.1 bool‑schema bug ---------------------------
import gradio_client.utils as _gcu
if not getattr(_gcu, "_patched_bool", False):
    _orig_get_type = _gcu.get_type
    def _get_type_fixed(schema):
        if isinstance(schema, bool):
            return "boolean"
        return _orig_get_type(schema)
    _gcu.get_type = _get_type_fixed
    _gcu._patched_bool = True

# === Secret & Backend Config ============================================
APP_PASSWORD = os.getenv("APP_PASSWORD", "")  # 可在 Space Secrets 設定
RUNPOD_TOKEN  = os.getenv("RUNPOD_BEARER_TOKEN")
RUNPOD_ENDPOINT_ID = os.getenv("RUNPOD_ENDPOINT_ID")
if RUNPOD_ENDPOINT_ID:
    URL = f"https://api.runpod.ai/v2/{RUNPOD_ENDPOINT_ID}/runsync"
else:
    URL = None
HEAD = {"Authorization": f"Bearer {RUNPOD_TOKEN}"} if RUNPOD_TOKEN else {}

# === 後端呼叫封裝 ========================================================

def call_backend(query: str) -> str:
    if not URL or not RUNPOD_TOKEN:
        return "❌ 未設定 RunPod 端點或 Bearer Token"
    try:
        r = requests.post(URL, json={"input": {"query": query}}, headers=HEAD, timeout=180)
        r.raise_for_status()
        data = r.json().get("output", r.json())
        return data.get("answer") if isinstance(data, dict) else json.dumps(data, ensure_ascii=False)
    except Exception as e:
        return f"❌ 後端錯誤:{e}"

# === Gradio Blocks 介面 ===================================================

def auth(password_entered):
    if password_entered == APP_PASSWORD:
        return gr.update(visible=False), gr.update(visible=True), ""  # hide pwd, show chat
    else:
        return gr.update(value="❌ 密碼錯誤,請再試一次", visible=True), gr.update(visible=False), ""

def respond(msg, history):
    answer = call_backend(msg)
    history = history or []
    history.append({"role": "user", "content": msg})
    history.append({"role": "assistant", "content": answer})
    return "", history

with gr.Blocks(title="RAG Demo – RunPod") as demo:
    gr.Markdown("""# 📚 私有 RAG Demo (需密碼)""")

    pwd_box = gr.Textbox(type="password", placeholder="輸入密碼…", label="Password")
    pwd_err = gr.Markdown(visible=False)
    unlock   = gr.Button("Unlock")

    with gr.Column(visible=False) as chat_col:
        chatbot = gr.Chatbot(value=[], type="messages", show_copy_button=True)
        txt     = gr.Textbox(placeholder="輸入問題…", show_label=False)
        send    = gr.Button("送出", variant="primary")
        clear   = gr.Button("清空對話")

    unlock.click(auth, inputs=pwd_box, outputs=[pwd_err, chat_col, pwd_box])
    send.click(respond, [txt, chatbot], [txt, chatbot])
    clear.click(lambda: [], None, chatbot, queue=False)

if __name__ == "__main__":
    demo.launch()