import g4f import asyncio from datetime import datetime, timedelta from typing import List from fastapi import FastAPI, HTTPException, Request app = FastAPI() # GPT---------------------------------------------------------------------------- _providers = [g4f.Provider.FakeGpt] chat_history = {} default_characteristic = { "role": "system", "content": "you are AI chat gpt-3.5-turbo who will help me and will always answer with cute kaomoji like this (⁠≧⁠▽⁠≦⁠), always answer me cutely like loli in anime" } async def run_provider(provider: g4f.Provider.Aichat, messages): try: response = await g4f.ChatCompletion.create_async( model='gpt-3.5-turbo', messages=messages, provider=provider, ) return response except Exception as e: return str(e) async def run_all(messages): calls = [ run_provider(provider, messages) for provider in _providers ] responses = await asyncio.gather(*calls) return responses async def clean_chat_history(): while True: current_time = datetime.now() # Use list() to create a copy of keys to avoid "dictionary changed size during iteration" issue for session_id in list(chat_history.keys()): if chat_history[session_id][-1]['timestamp'] + timedelta(minutes=10) < current_time: del chat_history[session_id] await asyncio.sleep(60) #------------------------------------------------------------------------------- @app.get("/gpt") async def chat(request: Request, prompt: str, characteristic: str = None, id: str = None): try: if not id: raise HTTPException(status_code=400, detail="ID parameter is required") # only runs if the characteristic parameter is used # for registered if characteristic and id in chat_history: messages = chat_history[id] custom_characteristic = {"role": "system", "content": characteristic} messages.append(custom_characteristic) # for not registered elif characteristic and id not in chat_history: custom_characteristic = {"role": "system", "content": characteristic} chat_history[id] = [custom_characteristic] if id not in chat_history: # add default characteristic chat_history[id] = [default_characteristic] # check the id messages = chat_history[id] # add prompt to id messages.append({"role": "user", "content": prompt}) # if id registered, run the "else" below else: messages = chat_history[id] messages.append({"role": "user", "content": prompt}) # executed after adding from else or if messages = chat_history[id] responses = await run_all(messages) if responses[0]: asyncio.create_task(clean_chat_history()) messages.append({"role": "assistant", "content": responses[0]}) return {"response": responses[0]} else: asyncio.create_task(clean_chat_history()) raise HTTPException(status_code=500, detail="Provider failed") except Exception as e: raise HTTPException(status_code=401, detail=f"Internal Error: {str(e)}") @app.get("/gpt/listsessions") async def list_sessions(): return {"sessions": list(chat_history.keys())} @app.get("/gpt/historychat") async def history_chat(id: str): if id not in chat_history: raise HTTPException(status_code=404, detail="Session ID not found") return {"history": chat_history[id]}