import gradio as gr import json import bcrypt import os from huggingface_hub import HfApi import whisper import torch from transformers import AutoTokenizer, AutoModelForCausalLM from datetime import datetime # === Hugging Face settings === REPO_ID = "dit-brugernavn/brugere-db" # ← SKIFT DETTE HF_TOKEN = os.getenv("HF_TOKEN") BRUGERE_FIL = "brugere.json" CHATLOG_FIL = "chatlog.json" STEMMETEKST_FIL = "stemmtekst.json" api = HfApi() # === Helper-funktioner === def load_json_from_hf(filename): try: content = api.repo_file_download(repo_id=REPO_ID, path_in_repo=filename, token=HF_TOKEN) with open(content, "r", encoding="utf-8") as f: return json.load(f) except Exception: return {} def save_json_to_hf(data, filename): content = json.dumps(data, ensure_ascii=False, indent=2) api.upload_file( path_or_fileobj=content.encode("utf-8"), path_in_repo=filename, repo_id=REPO_ID, repo_type="repo", token=HF_TOKEN, commit_message=f"Opdater {filename}", ) # === Brugerstyring === def opret_bruger(brugernavn, kodeord, rolle, email): brugere = load_json_from_hf(BRUGERE_FIL) if brugernavn in brugere: return "Brugernavn findes allerede" hashed = bcrypt.hashpw(kodeord.encode(), bcrypt.gensalt()).decode() brugere[brugernavn] = { "hash": hashed, "rolle": rolle, "email": email } save_json_to_hf(brugere, BRUGERE_FIL) return f"Bruger '{brugernavn}' oprettet som {rolle}" def tjek_login(brugernavn, kodeord): brugere = load_json_from_hf(BRUGERE_FIL) data = brugere.get(brugernavn) if not data: return False return bcrypt.checkpw(kodeord.encode(), data["hash"].encode()) # === Modeller === model_name = "NousResearch/Nous-Hermes-2-Mistral-7B-DPO" tokenizer = AutoTokenizer.from_pretrained(model_name, use_fast=False) model = AutoModelForCausalLM.from_pretrained( model_name, torch_dtype=torch.float16, device_map="auto", trust_remote_code=True ) whisper_model = whisper.load_model("base") # === Funktioner === def dansk_chat(brugernavn, message, history=[]): prompt = f"Bruger: {message}\nAI:" inputs = tokenizer(prompt, return_tensors="pt").to("cuda") outputs = model.generate(**inputs, max_new_tokens=200, pad_token_id=tokenizer.eos_token_id) response = tokenizer.decode(outputs[0], skip_special_tokens=True) svar = response.split("AI:")[-1].strip() chatlog = load_json_from_hf(CHATLOG_FIL) now = datetime.utcnow().isoformat() if brugernavn not in chatlog: chatlog[brugernavn] = [] chatlog[brugernavn].append({"timestamp": now, "message": message, "response": svar}) save_json_to_hf(chatlog, CHATLOG_FIL) return svar def transskriber(brugernavn, audio): if audio is None: return "" text = whisper_model.transcribe(audio)["text"].strip() stemmetekst = load_json_from_hf(STEMMETEKST_FIL) now = datetime.utcnow().isoformat() if brugernavn not in stemmetekst: stemmetekst[brugernavn] = [] stemmetekst[brugernavn].append({"timestamp": now, "text": text}) save_json_to_hf(stemmetekst, STEMMETEKST_FIL) return text # === Gradio UI === with gr.Blocks() as demo: with gr.Tab("Opret bruger"): ny_brugernavn = gr.Textbox(label="Nyt brugernavn") nyt_kodeord = gr.Textbox(label="Kodeord", type="password") ny_email = gr.Textbox(label="Email") rolle_vælger = gr.Dropdown(label="Rolle", choices=["bruger", "super", "admin"], value="bruger") opret_knap = gr.Button("Opret bruger") opret_status = gr.Textbox(label="Status", interactive=False) with gr.Tab("Login"): brugernavn = gr.Textbox(label="Brugernavn") kodeord = gr.Textbox(label="Kodeord", type="password") login_knap = gr.Button("Login") login_status = gr.Textbox(label="Status", interactive=False) with gr.Tab("Chatbot") as chat_tab: chat_tab.visible = False gr.Markdown("## Tal eller skriv med AI'en") mikrofon = gr.Microphone(type="filepath", label="Tal dansk her") lyd_tekst = gr.Textbox(label="Transskriberet tekst") besked = gr.Textbox(label="Eller skriv en besked") svar = gr.Textbox(label="Svar fra AI") send_knap = gr.Button("Send") # === Callbacks === def handle_opret(brugernavn, kodeord, rolle, email): return opret_bruger(brugernavn, kodeord, rolle, email) opret_knap.click(handle_opret, inputs=[ny_brugernavn, nyt_kodeord, rolle_vælger, ny_email], outputs=opret_status) def handle_login(bruger, kode): if tjek_login(bruger, kode): chat_tab.visible = True return "Login godkendt" return "Forkert brugernavn eller kodeord" login_knap.click(handle_login, inputs=[brugernavn, kodeord], outputs=login_status) mikrofon.change(transskriber, inputs=[brugernavn, mikrofon], outputs=lyd_tekst) send_knap.click(dansk_chat, inputs=[brugernavn, besked], outputs=svar) lyd_tekst.change(dansk_chat, inputs=[brugernavn, lyd_tekst], outputs=svar) demo.launch()