import gradio as gr from llama_cpp import Llama from huggingface_hub import hf_hub_download # 1. Téléchargement print("⬇️ Downloading model...") model_path = hf_hub_download( repo_id="XY26/dual-frame-llama-3", filename="meta-llama-3.1-8b-instruct.Q4_K_M.gguf" ) # 2. Chargement du Moteur print("⚙️ Loading engine...") llm = Llama( model_path=model_path, n_ctx=4096, n_threads=2, verbose=False ) def smart_response(message, history): try: messages = [] # --- LE CERVEAU (AMÉLIORÉ) --- # On définit des règles beaucoup plus strictes pour forcer le format system_prompt = """You are a Decision Architect AI designed to eliminate bias by presenting two opposite perspectives. CORE INSTRUCTION: Analyze the user's input to determine if it is a "Simple Fact" or a "Subjective Topic". CATEGORY 1: SIMPLE FACTS (Math, Geography, History, Names) -> Example: "Capital of France?", "Who invented X?", "1+1?" -> ACTION: Answer directly, briefly, and normally. CATEGORY 2: SUBJECTIVE TOPICS (Decisions, Debates, Social Issues, Opinions, "Should I...") -> Example: "Nuclear energy?", "Remote work?", "Buy a warranty?", "Is X good?" -> ACTION: You MUST output exactly TWO distinct sections. Do not write an introduction or conclusion. FORMAT FOR CATEGORY 2: **The Gain Frame (Positive)** [Focus strictly on benefits, success, safety, opportunities, and why it is a GOOD idea.] **The Loss Frame (Negative)** [Focus strictly on costs, risks, dangers, failure, and why it is a BAD idea.] """ messages.append({"role": "system", "content": system_prompt}) # 2. Mémoire Sécurisée for turn in history: if isinstance(turn, (list, tuple)) and len(turn) >= 2: user_msg = turn[0] bot_msg = turn[1] if user_msg and bot_msg: messages.append({"role": "user", "content": str(user_msg)}) messages.append({"role": "assistant", "content": str(bot_msg)}) # 3. Question Actuelle messages.append({"role": "user", "content": message}) # 4. Génération # On augmente un peu la temperature (0.8) pour qu'il soit plus créatif dans ses arguments stream = llm.create_chat_completion( messages=messages, max_tokens=1024, stream=True, temperature=0.8 ) partial_message = "" for chunk in stream: delta = chunk['choices'][0]['delta'] if 'content' in delta: token = delta['content'] partial_message += token yield partial_message except Exception as e: print(f"❌ Error: {e}") yield f"⚠️ Erreur technique : {e}. Cliquez sur 'New Chat'." # 3. Interface demo = gr.ChatInterface( fn=smart_response, title="🤖 Smart Decision Architect (V2)", description="I differentiate between FACTS (Direct Answer) and DEBATES (Gain/Loss Frames)." ) if __name__ == "__main__": demo.queue().launch(server_name="0.0.0.0", server_port=7860)