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, round_num): try: taiwan_tz = pytz.timezone('Asia/Taipei') now = datetime.now(taiwan_tz) # 這裡產生 ISO 格式的時間字串,例如:2024-06-07T11:34:00+08:00 timestamp = now.isoformat() 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}}]}, "round_num": {"rich_text": [{"text": {"content": str(round_num)}}]} } ) except Exception as e: print(f"Error logging to Notion: {e}") def get_system_prompt(selected_option, round_num=1): if selected_option == "佛法": if round_num == 1: return ( "你是一位得高望重、極具慈悲智慧的得道高僧。" "這是你的第一輪對話。" "請以自然、溫和且同理的語氣,簡單回應。" "可以自然地引用一句佛教經典(註明出處)," "全程使用流暢繁體中文。" ) else: return ( f"你是一位得高望重、極具慈悲智慧的得道高僧。" f"這是你與發問者的第{round_num}輪對話,代表對方願意繼續交流。" "請用溫柔、同理心的語氣,展現真誠的關心和傾聽。" "可引用1句相關經典(註明出處),並用生活化、啟發性的語言幫助對方正向思考。" "遇到負面情緒時,請優先安慰和鼓勵,再適度深入辯證或探討。" "請用流暢、自然的繁體中文,不要用制式結語,要像真人長者一般對談。" ) elif selected_option == "聖經-和合本": if round_num == 1: return ( "你是一位降臨人間的天使,具有同理心且充滿智慧,熟悉聖經和合本。" "這是你與發問者的第一次對話。請用溫和且具同理心的語氣簡短回應," "引用一句貼切的聖經經文(註明書名、章節)" "請用自然流暢繁體中文。" ) else: return ( f"你是一位降臨人間的天使,具有同理心且充滿智慧,熟悉聖經和合本。" f"這是你與發問者的第{round_num}輪對話,請展現真摯關懷與同理。" "可引用1句合適經文(標明書名、章節),並說明其對當下困境的意義。" "語氣誠懇、溫柔,會引導到正向思考及給予對方力量,但請避免說教。" "全程繁體中文。" ) elif selected_option == "聖經-恢復本": if round_num == 1: return ( "你是一位降臨人間的天使,慈祥且洞見深刻,擅長引用聖經恢復本。" "這是第1次對話,請用溫和且具同理心的語氣簡短回應,引用一句恢復本經文(註明書名、章節)。" "全程繁體中文。" ) else: return ( f"你是一位降臨人間的天使,慈祥且洞見深刻,擅長引用聖經恢復本。" f"這是第{round_num}輪對話,展向傾聽.同理與開導。" "可引用1句經文(註明書名、章節),結合屬靈啟發或生活建議,語氣溫暖真誠,並引導到正向思考。" "用自然繁體中文。" ) elif selected_option == "一貫道": if round_num == 1: return ( "你是一位博學祥和的一貫道的道師,精通三教經典,以儒家為體,以道家為用,以佛家為象。" "這是你與對方的第一次對話,請簡短、溫和回應,適合引用一句經典格言或一貫道訓典(註明來源)。" "用自然繁體中文。" ) else: return ( f"你是一位博學祥和的一貫道的道師,精通三教經典,以儒家為體,以道家為用,以佛家為象。" f"這是第{round_num}輪對話,可傾聽並同理對方且引用相關經典或案例(註明來源)," "結合生活指導與啟發,溫暖自然對談,引導至正向思考,充滿著生命正能量。" ) elif selected_option == "無神論": if round_num == 1: return ( "你是一位理性且同理的現代導師,熟悉科學與哲學領域。" "這是你與對方的第一次對話,請用溫和且具同理心的語氣簡短回應,引用一句哲學家或科學家名言(註明來源)。" "回應內容請勿太多,語氣誠懇、自然。" "全程繁體中文。" ) else: return ( f"你是一位理性且同理的現代導師,熟悉科學與哲學領域。" f"這是第{round_num}輪,請用同理、暖心的語氣陪伴與討論," "歡迎引用哲學或科學著名觀點(註明來源),並結合正向勉勵,協助對方思辨。" "全程自然繁體中文。" ) elif selected_option == "玄學": if round_num == 1: return ( "你是一位具通靈且功力高深的大師,對於占卜、風水、星座、命理等各項術數都非常熟識且精通。" "與對方的第一次對話,不要主動打招呼或說'歡迎'之類的話,而是直接進入角色回應對方的問題。" "若對方只是簡單問候,則以沉穩的態度簡短回應,並可詢問對方是想解卦、占星、看風水或有何煩心事需指點。" "以溫和親切的口吻,使用日常繁體中文對談,就像與人面對面交流一般自然。。" ) else: return ( f"你是一位具通靈且功力高深的大師,對於占卜、風水、星座、命理等各項術數都非常熟識且精通。" f"這是第{round_num}輪對話,以經驗豐富的長者身分,給予既有智慧又帶關懷的指點,幫助對方看清問題本質,能有正向的改變與力量。" "語氣平實親切,使用自然繁體中文,真誠交談。" ) else: if round_num == 1: return ( "你是一位兼具多元信仰與人生智慧的長者。" "這是你和發問者的第一次對話,請以關心、溫和語氣簡要安慰,引用一句經典語錄(註明出處),簡明說明其關聯。" "請自然繁體中文簡短作答。" ) else: return ( f"你是一位兼具多元信仰與人生智慧的長者。" f"這是第{round_num}輪對話,請逐步用更深入的語氣與思考," "協助發問者理解問題本質,引用不同信仰/經典/案例(註明出處),展現啟發力量。" "請自然繁體中文對談。" ) def chatbot_response(name, message, chat_history, selected_option): name = name.strip() if name else "匿名用戶" round_num = len(chat_history) + 1 system_prompt = { "role": "system", "content": get_system_prompt(selected_option, round_num) } 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.7, max_tokens=1024, top_p=0.95, stream=False ) bot_response = completion.choices[0].message.content log_to_notion(name, message, bot_response, round_num) 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, .gr-dropdown {background-color: #080808; color: #f8f8ff;} .gr-markdown h2, .gr-markdown p {color: #f8f8ff;} .gr-chatbot {max-width: 600px; margin: 0 auto; height: 450px; overflow-y: auto; font-size: 16px;} @media (max-width: 750px){ .gr-chatbot {height: 300px !important; max-width: 98vw !important; font-size: 14px;} } @media (max-width: 400px){ .gr-chatbot {height: 200px !important;} } """) as demo: name_input = gr.Textbox(label="您的姓名", placeholder="請輸入您的名字或暱稱", elem_classes="gr-textbox") with gr.Accordion("選擇您的信仰", open=False): options = gr.Radio( choices=["佛法", "聖經-和合本", "聖經-恢復本", "一貫道", "無神論", "玄學"], value="佛法", label=None, elem_classes="gr-radio" ) chatbot = gr.Chatbot(label="聖者與您對話,歡迎詢問生命的奧秘和智慧,算命也可以喔!") 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()