destiny / app.py
chuyk's picture
Update app.py
538e600 verified
import gradio_client.utils
orig__json_schema_to_python_type = gradio_client.utils._json_schema_to_python_type
def safe__json_schema_to_python_type(schema, defs=None):
if schema is True:
return "any"
if schema is False:
return "none"
return orig__json_schema_to_python_type(schema, defs)
gradio_client.utils._json_schema_to_python_type = safe__json_schema_to_python_type
orig_get_type = gradio_client.utils.get_type
def safe_get_type(schema):
if not isinstance(schema, dict):
return "any"
return orig_get_type(schema)
gradio_client.utils.get_type = safe_get_type
import os
import gradio as gr
from datetime import datetime
import pytz
try:
from groq import Groq
from notion_client import Client
except ImportError:
os.system('pip install groq notion-client pytz')
from groq import Groq
from notion_client import Client
# Initialize Groq and Notion clients
groq_client = Groq(api_key=os.getenv('groq_key'))
notion_client = Client(auth=os.getenv('NOTION_API_KEY'))
NOTION_DB_ID = os.getenv('NOTION_DB_ID')
def log_to_notion(name, user_input, bot_response):
try:
taiwan_tz = pytz.timezone('Asia/Taipei')
timestamp = datetime.now(taiwan_tz).strftime("%Y-%m-%d %H:%M:%S")
notion_client.pages.create(
parent={"database_id": NOTION_DB_ID},
properties={
"Name": {
"title": [{"text": {"content": name or "匿名用戶"}}]
},
"Timestamp": {
"date": {"start": timestamp}
},
"User Input": {
"rich_text": [{"text": {"content": user_input}}]
},
"Bot Response": {
"rich_text": [{"text": {"content": bot_response}}]
}
}
)
except Exception as e:
print(f"Error logging to Notion: {e}")
def get_system_prompt(selected_option):
if selected_option == "佛法":
return (
"你是一位智慧圓滿、慈悲充滿的佛教老師,與人對話時常用佛法、禪學與東方哲理為基礎。"
"每次回答請主動引用佛教經典(例如金剛經/心經/法句經/阿含經等)的原文、偈語、公案或譬喻,並標明出處,"
"用溫和、同理心、啟發式的語氣講解經文含義及其如何照亮對方當下的困惑。"
"善於傾聽並以正見引導對方發現智慧與平靜,遇到負面議題積極導回慈悲與希望與正念。"
"所有回答都用標準流暢的繁體中文,避免錯別字及中英夾雜。首次回應簡潔,持續追問可再深入。"
)
elif selected_option == "聖經-和合本":
return (
"你是一位身在人間的天使,專精聖經和合本。"
"每次回答請主動引用聖經和合本與問題相關的經文,明確標出書名、章、節(例如:馬太福音5:14),"
"並以溫暖正向的語氣解釋經文含義、故事背景,以及這段經文如何啟發提問者正向面對困境。"
"務必讓經文成為解答的依據和力量來源。所有回答都要用正確繁體中文,若引用其他語言請主動翻譯。"
"首次回覆簡短、重點明確,遇到負向提問積極導回正向。"
)
elif selected_option == "聖經-恢復本":
return (
"你是一位天使,專業於聖經恢復本(Recovery Version)。"
"回答時請主動引用恢復本裡與問題相關的經節,標明書名、章節(例如:約翰福音3:16),"
"以溫柔細膩、正向、同理心的語氣解釋經文意境、屬靈啟示與與當下問題的聯繫。"
"請著重恢復本的註解與信息,務求讓提問者透過經文獲得慰藉、希望與力量。"
"一律用正確繁體中文回答,有引用外文請主動翻譯。首次簡明回應,追問可加強。"
)
elif selected_option == "一貫道":
return (
"你是一位祥和、博學的道師,精通一貫道融合三教(儒、釋、道)義理。"
"請在回答時主動引用《中庸》《大學》《論語》《道德經》《金剛經》或一貫道訓典、經典格言(並說明來源),"
"解釋原文與當前提問的關聯,結合生活指導、修身養性之法協助對方。"
"語氣誠懇、啟發且正面,強調孝道、誠信、善行。回應務必全程用正確繁體中文。首次回答簡明重點,追問可詳述。"
)
elif selected_option == "無神論":
return (
"你是一位理性、開明且富同理心的現代思想導師,以科學、邏輯與哲學思維協助對方解析人生。"
"請每次回答主動引用著名科學家、哲學家(如愛因斯坦、卡繆、史蒂芬·霍金、羅素等)的名言或重要論點,並註明出處,"
"同時用淺白語言解釋這些理念怎麼啟發提問者面對現實。"
"鼓勵思辨、自信、實證,並溫和引導對方正面積極看待問題。所有回答均使用正確、清晰繁體中文。"
)
elif selected_option == "玄學":
return (
"你是一位豁達又神秘的東方玄學大師,精通易經、命理、風水、五行和占星等傳統術數。"
"回答時請主動引用易經卦辭、命理詩句、占星經典句、風水訓示,並標明出處或派別,"
"用啟發、鼓勵且富人生哲理的方式,說明這些典籍智慧如何助對方突破迷惘、發現新契機。"
"請全程以正確繁體中文作答,無中英混雜或錯字。初答簡要,後續可深入展開。"
)
else:
return (
"你是一位功力高強且德高望眾的通靈老師,善於用經典智慧協助發問者從不同信仰與學說找到人生啟示,並給予正向的力量。"
"回答主動引用各學派經典句子或案例做依據,並用繁體中文說明。"
)
def chatbot_response(name, message, chat_history, selected_option):
name = name.strip() if name else "匿名用戶"
system_prompt = {
"role": "system",
"content": get_system_prompt(selected_option)
}
messages = [system_prompt]
for human, assistant in chat_history or []:
messages.append({"role": "user", "content": human})
messages.append({"role": "assistant", "content": assistant})
messages.append({"role": "user", "content": message})
try:
completion = groq_client.chat.completions.create(
model="meta-llama/llama-4-maverick-17b-128e-instruct",
messages=messages,
temperature=0.8,
max_tokens=2048,
top_p=0.95,
stream=False
)
bot_response = completion.choices[0].message.content
log_to_notion(name, message, bot_response)
return bot_response
except Exception as e:
print(f"Groq API 調用錯誤: {e}")
return "很抱歉,我遇到了一些技術問題。請稍後再試。"
with gr.Blocks(css="""
.gradio-container {background: linear-gradient(to right, #ffecd2, #fcb69f);}
.gr-textbox {background-color: #080808; color: #f8f8ff;}
.gr-button {background-color: #080808; color: #f8f8ff; height: 100%;}
.gr-radio {background-color: #080808; color: #f8f8ff;}
.gr-markdown h2, .gr-markdown p {color: #f8f8ff;}
""") as demo:
name_input = gr.Textbox(label="您的姓名", placeholder="請輸入您的名字或暱稱", elem_classes="gr-textbox")
options = gr.Radio(
choices=["佛法", "聖經-和合本", "聖經-恢復本", "一貫道", "無神論", "玄學"],
label="選擇您的信仰",
value="佛法",
elem_classes="gr-radio"
)
chatbot = gr.Chatbot(label="聖者與您對話,歡迎詢問生命的奧秘和智慧,算命也可以喔!", height=450, value=[])
with gr.Row():
msg_input = gr.Textbox(label="您的訊息", placeholder="在此輸入您想詢問的問題", scale=8, elem_classes="gr-textbox")
submit_btn = gr.Button("送出", scale=1, elem_classes="gr-button")
clear_btn = gr.Button("清除對話", elem_classes="gr-button")
def submit_message(name, message, chat_history, selected_option):
chat_history = chat_history or []
response = chatbot_response(name, message, chat_history, selected_option)
chat_history.append((message, response))
return "", chat_history
def clear_chat():
return []
msg_input.submit(
submit_message,
[name_input, msg_input, chatbot, options],
[msg_input, chatbot]
)
submit_btn.click(
submit_message,
[name_input, msg_input, chatbot, options],
[msg_input, chatbot]
)
clear_btn.click(clear_chat, None, chatbot)
gr.Markdown("## 仁者見仁,智者見智")
if __name__ == "__main__":
demo.launch()