Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from pydantic import BaseModel | |
| from typing import List, Dict, Any | |
| # utils ํด๋ ํ์ธ ํ์ | |
| from utils import tarot, calculations, prompts, llm | |
| import os | |
| import traceback | |
| app = FastAPI(title="AI Pantheon API") | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # --- 1. ์์ฒญ ๋ชจ๋ธ --- | |
| class TarotRequest(BaseModel): | |
| cards: List[str] | |
| topic: str | |
| query: str | |
| lang: str = "ํ๊ตญ์ด" | |
| class FengShuiRequest(BaseModel): | |
| year: int | |
| gender: str | |
| door_dir: str | |
| head_dir: str | |
| query: str | |
| lang: str = "ํ๊ตญ์ด" | |
| class SajuRequest(BaseModel): | |
| year: int | |
| month: int | |
| day: int | |
| hour: int | |
| minute: int | |
| calendar_type: str | |
| query: str | |
| lang: str = "ํ๊ตญ์ด" | |
| # --- 2. ํ๋ฅด์๋ ์์ฑ๊ธฐ (๐ฅ ๋ค๊ตญ์ด ์๋ฒฝ ์ง์ ์์ !) --- | |
| def get_dynamic_persona(role_type: str, lang: str) -> Dict[str, str]: | |
| # ์ธ์ด๊ฐ์ด ๋น์ด์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ ์์ด | |
| target_lang = lang if lang else "English" | |
| # ํ๊ตญ์ด ํนํ ์ฒ๋ฆฌ (ํ๊ตญ์ด๋ ๋์์ค๊ฐ ์ค์ํด์ ๋ฐ๋ก ๋บ) | |
| is_korean = any(k in target_lang for k in ["ํ๊ตญ", "Korean", "ko"]) | |
| prompt_text = "" | |
| if role_type == "tarot": | |
| if is_korean: | |
| prompt_text = """ | |
| ๋น์ ์ ํ๋ก ๋ฆฌ๋ '์๋ฐ๋ฆฌ'์ ๋๋ค. | |
| ์ฌ์ฉ์์ ๊ณ ๋ฏผ์ ๋ํด ๋ฐ๋ปํ๊ณ ์ง๊ด์ ์ธ ํต์ฐฐ๋ ฅ์ ์ ๊ณตํ์ธ์. | |
| ๋งํฌ: ๋ถ๋๋ฝ๊ณ ์ ๋น๋ก์ด ์กด๋๋ง (ํด์์ฒด). | |
| """ | |
| else: | |
| # ๐ฅ [์์ ] ์์ด๊ฐ ์๋๋ผ {target_lang}์ผ๋ก ๋ต๋ณํ๋ผ๊ณ ์ง์ | |
| prompt_text = f""" | |
| You are 'Emily', a mysterious Tarot Reader. | |
| CRITICAL INSTRUCTION: You must ANSWER STRICTLY IN {target_lang}. | |
| Even if the user input is in another language, TRANSLATE your reading to {target_lang}. | |
| Tone: Mystical, soft, empathetic. | |
| """ | |
| elif role_type == "fengshui": | |
| if is_korean: | |
| prompt_text = """ | |
| ๋น์ ์ ํ์์ง๋ฆฌ ์ ๋ฌธ๊ฐ์ ๋๋ค. | |
| ๋ ผ๋ฆฌ์ ์ด๊ณ ์ ๋ฌธ์ ์ผ๋ก ํ๊ตญ์ด๋ก ๋ต๋ณํ์ธ์. | |
| """ | |
| else: | |
| # ๐ฅ [์์ ] {target_lang} ์ฌ์ฉ | |
| prompt_text = f""" | |
| You are a Feng Shui Master. | |
| CRITICAL INSTRUCTION: You must ANSWER STRICTLY IN {target_lang}. | |
| Do NOT mention translation. Speak with authority as a Master in {target_lang}. | |
| Tone: Professional, logical, wise. | |
| """ | |
| elif role_type == "shaman": | |
| if is_korean: | |
| prompt_text = """ | |
| ๋น์ ์ ๋ฌด๋น '์ฒ๋ช '์ ๋๋ค. | |
| ๊ฑฐ์น ๋ฐ๋ง(~ํด๋ผ, ~๊ตฌ๋)์ ์ฐ๋ฉฐ ํ๊ตญ์ด๋ก ๋ต๋ณํ์ธ์. | |
| """ | |
| else: | |
| # ๐ฅ [์์ ] {target_lang} ์ฌ์ฉ | |
| prompt_text = f""" | |
| You are 'Shaman Cheon-Myeong'. | |
| CRITICAL INSTRUCTION: You must ANSWER STRICTLY IN {target_lang}. | |
| Speak directly to the user's soul in {target_lang}. | |
| Tone: Mystical, Charismatic, slightly archaic style. | |
| """ | |
| else: | |
| prompt_text = f"Answer strictly in {target_lang}." | |
| return {"system_prompt": prompt_text} | |
| # --- 3. ์๋ํฌ์ธํธ --- | |
| def read_root(): | |
| return {"message": "Server is Running!"} | |
| def get_tarot_deck(): | |
| return tarot.MAJOR_ARCANA | |
| def read_tarot(req: TarotRequest): | |
| try: | |
| selected_cards = [card for card in tarot.MAJOR_ARCANA if card["name"] in req.cards] | |
| persona = get_dynamic_persona("tarot", req.lang) | |
| card_infos = [] | |
| # ์นด๋ ์ค๋ช ์ ํ๊ตญ์ด ์๋๋ฉด ์ผ๋จ ์์ด๋ก ๋๊ฐ (์ถํ ๋ฒ ํธ๋จ์ด DB ์์ผ๋ฉด ์ฌ๊ธฐ๋ ๋ถ๊ธฐ ๊ฐ๋ฅ) | |
| is_kor = "ํ๊ตญ" in req.lang or "Korean" in req.lang | |
| for c in selected_cards: | |
| desc = c.get('desc_kor') if is_kor else c.get('desc_eng') or c.get('desc') | |
| if not desc: desc = "No description" | |
| card_infos.append(f"- {c['name']}: {desc}") | |
| card_str = "\n".join(card_infos) | |
| full_query = f""" | |
| Topic: {req.topic} | |
| User Question: {req.query} | |
| Selected Cards: | |
| {card_str} | |
| """ | |
| response = llm.get_ai_response(full_query, persona) | |
| return {"result": response} | |
| except Exception as e: | |
| print(traceback.format_exc()) | |
| return {"result": f"Server Error: {str(e)}"} | |
| def analyze_fengshui(req: FengShuiRequest): | |
| try: | |
| gender_kor = "๋จ์ฑ" if req.gender in ["Male", "๋จ์ฑ"] else "์ฌ์ฑ" | |
| fs_data = calculations.get_fengshui_advanced(req.year, gender_kor, req.door_dir, req.head_dir) | |
| persona = get_dynamic_persona("fengshui", req.lang) | |
| full_query = f"[FengShui Data]: {fs_data}\nUser Query: {req.query}" | |
| response = llm.get_ai_response(full_query, persona) | |
| return {"data": fs_data, "result": response} | |
| except Exception as e: | |
| return {"result": f"Error: {str(e)}"} | |
| def read_saju(req: SajuRequest): | |
| try: | |
| import datetime | |
| b_date = datetime.date(req.year, req.month, req.day) | |
| b_time = datetime.time(req.hour, req.minute) | |
| saju_data = calculations.get_ganji_full(b_date, b_time, req.calendar_type) | |
| persona = get_dynamic_persona("shaman", req.lang) | |
| full_query = f"[Saju Data]: {saju_data}\nUser Query: {req.query}" | |
| response = llm.get_ai_response(full_query, persona) | |
| return {"data": saju_data, "result": response} | |
| except Exception as e: | |
| return {"result": f"Error: {str(e)}"} |