import openai import uvicorn from typing import List from pydantic import BaseModel from fastapi import FastAPI, Body from fastapi.middleware.cors import CORSMiddleware from langchain.schema import SystemMessage, AIMessage, HumanMessage from langchain_core.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langchain.callbacks import get_openai_callback import os from dotenv import load_dotenv load_dotenv() from supabase.client import Client, create_client supabase_url = os.environ.get("SUPABASE_URL") supabase_key = os.environ.get("SUPABASE_KEY") supabase: Client = create_client(supabase_url, supabase_key) chat_model = ChatOpenAI(model='gpt-4o-mini') app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) from semantic_search import semantic_cache from api import whisper app.include_router(whisper.router, prefix='/whisper', tags=['whisper']) class ChatHistoryItem(BaseModel): q: str a: str @app.post("/chat/") async def chat(message, chat_history: List[ChatHistoryItem] = Body(...)): print(chat_history) messages_list = [ SystemMessage(content="你是一名日照中心的志工,你的職責是陪伴老人聊天,你需要考量到老人的健康與安全,並能安撫老人,只有家人准許時才能離開日照中心。請用繁體中文"), AIMessage(content="你好!很高興能和您聊天。今天您過得怎麼樣呢?有沒有什麼想分享的事情?") ] for item in chat_history[-10:]: if item.q == "string" or item.a == "string" : continue messages_list.append(HumanMessage(content=item.q)) messages_list.append(AIMessage(content=item.a)) messages_list.append(HumanMessage(content=message)) print(messages_list) prompt = ChatPromptTemplate( messages=messages_list ) try: with get_openai_callback() as cb: # cache_question, cache_answer = semantic_cache(supabase, message) cache_question, cache_answer, video_cache = semantic_cache(supabase, message, SIMILARITY_THRESHOLD=0.83) if cache_answer: save_history(message, cache_answer) # return {"message": cache_answer} if video_cache is not None: return {"message": cache_answer, "video_cache": video_cache} else: return {"message": cache_answer} AIMessage_ = chat_model.invoke(prompt.format_messages()).content save_history(message, AIMessage_) except openai.RateLimitError as e: print(f"Rate limit exceeded: {e}") return {'message': "Current quota exceeded."} return {"message": AIMessage_} def save_history(question, answer): response = ( supabase.table("INNOLUX_record") .insert({"question": question, "answer": answer}) .execute() ) from starlette.responses import JSONResponse @app.get("/health") # 使用網址給 kuma 監測 async def health_check(): return JSONResponse(content={"status": "ok"}, status_code=200) if __name__ == "__main__": try: uvicorn.run("app:app", reload=False, port=8087, host='cmm.ai', ssl_keyfile="/etc/letsencrypt/live/cmm.ai/privkey.pem", ssl_certfile="/etc/letsencrypt/live/cmm.ai/fullchain.pem") finally: import shutil cache_db = "chroma_db" shutil.rmtree(cache_db)