import os import gradio as gr import time import uuid from typing import Dict, List import markdown import re from pygments import highlight from pygments.lexers import get_lexer_by_name from pygments.formatters import HtmlFormatter # Untuk integrasi dengan model AI (misalnya Hugging Face Transformers atau API eksternal) import requests from transformers import AutoTokenizer, AutoModelForCausalLM import torch # Konfigurasi dasar AI_MODEL_ID = os.environ.get("AI_MODEL_ID", "TheBloke/Mistral-7B-Instruct-v0.2-GPTQ") API_TOKEN = os.environ.get("HUGGINGFACE_API_TOKEN", None) MAX_HISTORY_LENGTH = 10 DEVICE = "cuda" if torch.cuda.is_available() else "cpu" # Dictionary untuk menyimpan semua sesi chat active_sessions: Dict[str, List[Dict]] = {} # Inisialisasi model dan tokenizer @torch.inference_mode() def initialize_model(): try: print(f"Loading model {AI_MODEL_ID} on {DEVICE}...") tokenizer = AutoTokenizer.from_pretrained(AI_MODEL_ID) model = AutoModelForCausalLM.from_pretrained( AI_MODEL_ID, device_map=DEVICE, torch_dtype=torch.float16 if DEVICE == "cuda" else torch.float32 ) print("Model loaded successfully!") return model, tokenizer except Exception as e: print(f"Error loading model: {e}") return None, None model, tokenizer = initialize_model() # Fungsi untuk memformat kode dengan syntax highlighting def format_code_blocks(text): def replace_code_block(match): language = match.group(1) or "python" code = match.group(2) try: lexer = get_lexer_by_name(language, stripall=True) formatter = HtmlFormatter(style="github", cssclass="syntax-highlight") result = highlight(code, lexer, formatter) return f'
{code}
'
# Cari dan ganti semua code blocks markdown
pattern = r'```(\w+)?\n([\s\S]+?)\n```'
return re.sub(pattern, replace_code_block, text)
# Fungsi untuk memproses pesan dan mendapatkan respons AI
@torch.inference_mode()
def process_message(message, history, session_id):
if session_id not in active_sessions:
active_sessions[session_id] = []
# Tambahkan pesan pengguna ke history sesi
if len(active_sessions[session_id]) >= MAX_HISTORY_LENGTH:
active_sessions[session_id].pop(0)
active_sessions[session_id].append({"role": "user", "content": message})
# Konversi history ke format prompt untuk model
prompt = format_prompt(active_sessions[session_id])
# Jalankan inferensi dengan animasi loading
yield "⌛ Thinking..."
time.sleep(0.5)
yield "⌛ Generating response..."
try:
# Gunakan model untuk generate respons
inputs = tokenizer(prompt, return_tensors="pt").to(DEVICE)
output = model.generate(
inputs["input_ids"],
max_length=2048,
temperature=0.7,
top_p=0.9,
do_sample=True,
pad_token_id=tokenizer.eos_token_id
)
# Proses output
response = tokenizer.decode(output[0], skip_special_tokens=True)
# Ekstrak hanya bagian respons AI dari keseluruhan output
ai_response = extract_ai_response(response, prompt)
# Tambahkan respons AI ke history sesi
active_sessions[session_id].append({"role": "assistant", "content": ai_response})
# Format respons dengan markdown dan syntax highlighting untuk kode
formatted_response = format_code_blocks(markdown.markdown(ai_response))
return formatted_response
except Exception as e:
error_msg = f"Error generating response: {str(e)}"
print(error_msg)
return f"{error_msg}"
# Format prompt sesuai dengan kebutuhan model
def format_prompt(messages):
prompt = ""
for msg in messages:
if msg["role"] == "user":
prompt += f"USER: {msg['content']}\n"
else:
prompt += f"ASSISTANT: {msg['content']}\n"
prompt += "ASSISTANT: "
return prompt
# Ekstrak respons AI dari output model
def extract_ai_response(full_response, prompt):
# Hapus prompt dari respons untuk mendapatkan hanya output baru
if full_response.startswith(prompt):
return full_response[len(prompt):].strip()
return full_response.strip()
# Fungsi untuk membuat sesi baru
def create_new_session():
session_id = str(uuid.uuid4())
active_sessions[session_id] = []
return session_id, []
# Debug mode untuk membantu debugging kode
def debug_code(code, session_id):
try:
# Simulasi proses debugging
yield "🔍 Analyzing code..."
time.sleep(1)
# Cek sintaks dasar
compile(code, '